问题描述:

For example I have handler:

@Component

public class MyHandler {

@AutoWired

private MyDependency myDependency;

public int someMethod() {

...

return anotherMethod();

}

public int anotherMethod() {...}

}

to testing it I want to write something like this:

@RunWith(MockitoJUnitRunner.class}

class MyHandlerTest {

@InjectMocks

private MyHandler myHandler;

@Mock

private MyDependency myDependency;

@Test

public void testSomeMethod() {

when(myHandler.anotherMethod()).thenReturn(1);

assertEquals(myHandler.someMethod() == 1);

}

}

But it actually calls anotherMethod() whenever I try to mock it. What should I do with myHandler to mock its methods?

网友答案:

First of all the reason for mocking MyHandler methods can be the following: we already test anotherMethod() and it has complex logic, so why do we need to test it again (like a part of someMethod()) if we can just verify that it's calling?
We can do it through:

@RunWith(MockitoJUnitRunner.class}
class MyHandlerTest {

  @Spy  
  @InjectMocks  
  private MyHandler myHandler;  

  @Mock  
  private MyDependency myDependency;  

  @Test  
  public void testSomeMethod() {  
    doReturn(1).when(myHandler).anotherMethod();  
    assertEquals(myHandler.someMethod() == 1);  
    verify(myHandler, times(1)).anotherMethod();  
  }  
}  
网友答案:

In your code, you are not testing MyHandler at all. You don't want to mock what you are testing, you want to call its actual methods. If MyHandler has dependencies, you mock them.

Something like this:

public interface MyDependency {
  public int otherMethod();
}

public class MyHandler {
  @AutoWired
  private MyDependency myDependency;

  public void someMethod() {
    myDependency.otherMethod();
  }
}

And in test:

private MyDependency mockDependency;
private MyHandler realHandler;

@Before
public void setup() {
   mockDependency = Mockito.mock(MyDependency.class);
   realHandler = new MyHandler();
   realhandler.setDependency(mockDependency); //but you might Springify this 
}

@Test
public void testSomeMethod() {

  //specify behaviour of mock
  when(mockDependency.otherMethod()).thenReturn(1);

  //really call the method under test
  realHandler.someMethod();
}

The point is to really call the method under test, but mock any dependencies they may have (e.g. calling method of other classes)

If those other classes are part of your application, then they'd have their own unit tests.

NOTE the above code could be shortened with more annotations, but I wanted to make it more explicit for the sake of explanation (and also I can't remember what the annotations are :) )

相关阅读:
Top