Mocking member variables of a class using Mockito

前端 未结 9 1796
醉话见心
醉话见心 2020-12-07 10:24

I am a newbie to development and to unit tests in particular . I guess my requirement is pretty simple, but I am keen to know others thoughts on this.

Suppose I h

相关标签:
9条回答
  • 2020-12-07 10:36

    Lots of others have already advised you to rethink your code to make it more testable - good advice and usually simpler than what I'm about to suggest.

    If you can't change the code to make it more testable, PowerMock: https://code.google.com/p/powermock/

    PowerMock extends Mockito (so you don't have to learn a new mock framework), providing additional functionality. This includes the ability to have a constructor return a mock. Powerful, but a little complicated - so use it judiciously.

    You use a different Mock runner. And you need to prepare the class that is going to invoke the constructor. (Note that this is a common gotcha - prepare the class that calls the constructor, not the constructed class)

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({First.class})
    

    Then in your test set-up, you can use the whenNew method to have the constructor return a mock

    whenNew(Second.class).withAnyArguments().thenReturn(mock(Second.class));
    
    0 讨论(0)
  • This is not possible if you can't change your code. But I like dependency injection and Mockito supports it:

    public class First {    
        @Resource
        Second second;
    
        public First() {
            second = new Second();
        }
    
        public String doSecond() {
            return second.doSecond();
        }
    }
    

    Your test:

    @RunWith(MockitoJUnitRunner.class)
    public class YourTest {
       @Mock
       Second second;
    
       @InjectMocks
       First first = new First();
    
       public void testFirst(){
          when(second.doSecond()).thenReturn("Stubbed Second");
          assertEquals("Stubbed Second", first.doSecond());
       }
    }
    

    This is very nice and easy.

    0 讨论(0)
  • 2020-12-07 10:46

    If you can't change the member variable, then the other way around this is to use powerMockit and call

    Second second = mock(Second.class)
    when(second.doSecond()).thenReturn("Stubbed Second");
    whenNew(Second.class).withAnyArguments.thenReturn(second);
    

    Now the problem is that ANY call to new Second will return the same mocked instance. But in your simple case this will work.

    0 讨论(0)
提交回复
热议问题