我如何模拟@InjectMocks类的方法?

时间:2015-06-11 07:29:53

标签: java unit-testing mocking mockito

例如我有处理程序:

@Component
public class MyHandler {

  @AutoWired
  private MyDependency myDependency;

  public int someMethod() {
    ...
    return anotherMethod();
  }

  public int anotherMethod() {...}
}

测试它我想写这样的东西:

@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);
  }
}

但每当我试图嘲笑它时,它实际上会调用anotherMethod()。我应该如何处理myHandler来模拟其方法?

2 个答案:

答案 0 :(得分:77)

首先,模拟MyHandler方法的原因如下:我们已经测试anotherMethod()并且它具有复杂的逻辑,那么为什么我们需要再次测试它(就像someMethod()的一部分一样)如果我们可以verify它正在打电话吗? 我们可以通过以下方式实现:

@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();  
  }  
}  

注意:如果是'间谍'对象我们需要使用doReturn代替thenReturn(很少解释here

答案 1 :(得分:0)

在您的代码中,您根本不会测试MyHandler。你不想模拟你正在测试的东西,你想要调用它的实际方法。如果MyHandler有依赖关系,你可以模拟它们。

这样的事情:

public interface MyDependency {
  public int otherMethod();
}

public class MyHandler {
  @AutoWired
  private MyDependency myDependency;

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

在测试中:

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();
}

重点是要真正调用测试中的方法,但是模拟它们可能具有的任何依赖关系(例如调用其他类的方法)

如果那些其他类是你的应用程序的一部分,那么他们就有自己的单元测试。

注意上面的代码可以通过更多注释缩短,但为了解释起见,我想让它更明确(而且我也记不起注释是什么:)) / p>