2011-12-22 172 views
2

如何在getData()模拟测试期间在嵌套方法中侦测参数'param'? Easymock 3可以吗?Easymock - 嵌套void方法测试(间谍)

的源代码

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()被调用,参数是否正确?!

+0

你是什么意思的间谍?你可以期待serviceDAO.executeStatement并为param赋予约束。 – aishwarya 2011-12-22 08:12:39

+0

param在哪里设置?你可以将它传递给构造函数中的ServiceLogic吗?还是有一个二传手?如果有,你可以使用和验证。 – 2011-12-22 08:18:11

回答

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(行为Driven Development)风格来指导我进行我想测试的内容。我鼓励你练习它,你可以看看wiki page

因此,对于你的问题,你应该看看verify线,它把模拟的验证模式,因此实际上可以验证该方法executeStatement实际上是调用参数值"expected param"

如果你有更复杂的参数,你可以使用Hamcrestlibrary使用一些匹配器:

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

+0

+1用于FEST-Assert库的介绍。非常有趣的替代Hamcrest(我喜欢和目前使用)。 – jhericks 2011-12-22 17:01:25

0

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

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

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

这几乎可以完成测试保存断言。它适用于最终的,静态的,抽象的和任何方法。

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做,只是用更多的代码行。