Why can't I use @InjectMocks field matching when running with PowerMockRunner?

≯℡__Kan透↙ 提交于 2020-05-29 00:45:49

问题


I've run into an issue in which the field injection matching for Mockito's @Mock annotation for @InjectMocks is not working in the case where there are 2 @Mocks of the same type. I've used the @Mock (name = "name_of_var") syntax as well, but it still failed...

Here is the class under test:

    import java.util.Date;
    public class Parent{

    private Date dateA;
    private Date dateB;

    public void setDateA(Date _dateA){
       dateA = _dateA;
    }

    public void setDateB(Date _dateB){
       dateB = _dateB;
    }

    public Date getDateA(){
       return dateA;
    }

    public Date getDateB(){
       return dateB;
    }

Here is the test itself:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({System.class, Parent.class})
    public class testParent{

    @Mock (name = "dateB")  private Date someOtherDate;
    @Mock (name = "dateA")  private Date someDate;    

    @InjectMocks Parent p;

    @Before
    public void setup(){
        Mockito.when(someOtherDate.getTime()).thenReturn(500l);
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.currentTimeMillis()).thenReturn(2000l);
    }

    @Test
    public void testGetDateAGetTimeShouldReturn1000() {
        Mockito.when(someDate.getTime()).thenReturn(1000l);
        Date result = p.getDateA();
        assertEquals(1000l, result.getTime());
    }

    @Test
    public void testGetDateBGetTimeShouldReturn500() {
        Date result = p.getDateB();
        assertEquals(500l, result.getTime());   
    }

When tested, both assertEquals cause a NullPointerException due to the fact that the @InjectMocks did not work.

Now, when I replaced @RunWith(PowerMockRunner.class) with @RunWith(MockitoJUnitRunner.class), it WORKS just fine.

Also, if I had just defined 1 Date variable ( say, dateA ) in Parent.java and a matching mock to inject in ParentTest, it would inject just fine using PowerMockRunner.class.

The reason I must run with PowerMockRunner.class is because I must be able to mock static functions as well as constructors.

I am running with Junit4.12, Mockito-all-1.10.19, and PowerMock-mockito-1.6.2-full.

Does anyone see the cause of why it does not inject properly with PowerMockRunner.class? Is there a workaround for this while running with PowerMockRunner.class?


回答1:


If you are going to use PowerMockRunner, you have to call MockitoAnnotations.initMocks() in order to initialize the mocks that are created using the annotations.

However, there are several good reasons not to use InjectMocks at all. Generally speaking, you have less control over how your test is set up. It's better to just call new and pass the arguments in manually. Also, if there's any sort of a problem Mockito will just fail silently. See more in this article:

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won’t report failure; i.e. you will have to provide dependencies yourself.



来源:https://stackoverflow.com/questions/32263208/why-cant-i-use-injectmocks-field-matching-when-running-with-powermockrunner

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!