Easymock - 嵌套的void方法测试(间谍)

时间:2011-12-22 08:01:05

标签: java junit4 mockito easymock

如何在getData()模拟测试期间在嵌套方法中监视参数'param'? 是否可以使用Easymock 3?

源代码

public class ServiceLogic {

 public void getData(){

  // some business logic

  serviceDAO.executeStatement(param);   

 }

}

Easymock测试:

ServiceLogic _serviceLogicMock = EasyMock.createNiceMock(ServiceLogic.class);
ServiceDAO _serviceDAOMock = EasyMock.createNiceMock(ServiceDAO .class);

_serviceLogicMock.setServiceDAO(_serviceDAOMock);

//some other method calls -> .execute(...).andReturn(...);
EasyMock.replay(_serviceLogicMock);

//run
_serviceLogicMock.getData();

如何使用EasyMock检查是否使用正确的参数调用executeStatement()方法?

3 个答案:

答案 0 :(得分:2)

您的测试确实有误:

  • 您的单元测试是关于测试ServiceLogic为什么要嘲笑它?
  • 此外,您对ServiceDAO模拟的任何互动都没有任何期望。

由于问题标记为Mockito,我建议您可以适应代码的以下解决方案(减去导入):

@RunWith(MockitoJUnitRunner.class)
public class ServiceLogicTest {
    @Mock ServiceDAO serviceDAO;
    @InjectMocks ServiceLogic serviceLogic;

    @Test
    public void ensure_executeStatement_is_called_with_right_param() throws Exception {
        // given
        String input = "Some input";

        // when
        serviceLogic.getDataFrom(input);

        // then
        verify(serviceDAO).executeStatement("expected param");
    }
}

在编写测试时,我喜欢使用BDD(行为驱动开发)样式来指导我想要测试的内容。我鼓励你练习它,你可以查看wiki page

因此,对于您的问题,您应该查看verify行,它将模拟放入验证模式,因此可以实际验证方法executeStatement实际上是使用参数值调用的"expected param"

如果您有更复杂的参数,可以使用Hamcrest library使用某些匹配器:

verify(serviceDAO).executeStatement(argThat(hasProperty("propertyName")));

或者您可以将Mockito ArgumentCaptorFEST-Assert library结合使用(通常是我的首选方法):

ArgumentCaptor<ComplexArgument> argCaptor = ArgumentCaptor.forClass(ComplexArgument.class);
verify(serviceDAO).executeStatement(argCaptor.capture());
assertThat(argCaptor.getValue()).isNotNull().satisfies(myComplexArgumentCondition());

主要想法是在测试代码中的生产代码中使用understandable code

如需进一步阅读,请查看Mockito Javadoc

答案 1 :(得分:2)

与@Brice一样,我更喜欢Mockito和EasyMock,但是这里的EasyMock版本更接近原始示例,因为您的示例是EasyMock。

public class ServiceLogicTest {

    @Test
    public void ensure_executeStatement_is_called_with_right_param() throws Exception {
        ServiceLogic _serviceLogicUT = new ServiceLogic();
        ServiceDAO _serviceDAOMock = EasyMock.createNiceMock(ServiceDAO .class);

        _serviceLogicUT.setServiceDAO(_serviceDAOMock);

        String input = "Some input";

        //some other method calls -> .execute(...).andReturn(...);
        _serviceDaoMock.executeStatement("expected para");  // assuming a void method
        EasyMock.replay(_serviceDaoMock);            
        // run
        _serviceLogicUT.getDataFrom(input);

        // verifies that the expected calls were made
        EasyMock.verify(_serviceDaoMock);  
    }
}

EasyMock还具有参数捕获功能。这看起来像这样:

public class ServiceLogicTest {

    @Test
    public void ensure_executeStatement_is_called_with_right_param() throws Exception {
        ServiceLogic _serviceLogicUT = new ServiceLogic();
        ServiceDAO _serviceDAOMock = EasyMock.createNiceMock(ServiceDAO .class);

        _serviceLogicUT.setServiceDAO(_serviceDAOMock);

        String input = "Some input";

        //some other method calls -> .execute(...).andReturn(...);
        Capture<ComplexParam> capturedParam = new Capture<ComplexParam>();
        _serviceDaoMock.executeStatement(EasyMock.capture(capturedParam));  // assuming a void method
        EasyMock.replay(_serviceDaoMock);            
        // run
        _serviceLogicUT.getDataFrom(input);

        ComplexParam actualParam = capturedParam.getValue();

        // make various assertions on actual param
    }
}

我认为你可以从这两个例子中看出为什么很多人更喜欢Mockito,但是如果有一些你更喜欢或者被要求使用EasyMock的原因,你可以做任何你可以用Mockito做的事情,只需要更多的代码行

答案 2 :(得分:0)

这应该可以使用jmockit,除非你DAO有最终方法。但是,使用jMockit可以更好,更轻松地完成:

@Test
public void testMethod(@Mocked final ServiceDAO serviceDAO) {
       new Expectations() {{
            serviceDAO.executeStatement(expectedOParams);returns(expectedReturnValue)
       }};

     (new ServiceLogic(serviceDAO)).getData();
}

这几乎是完全测试保存断言。它适用于final,static,abstract和任何方法。