我试图实现Mockito来测试一个特定的方法但是.thenReturn(...)似乎总是返回一个null对象而不是我想要的:
CUT:
public class TestClassFacade {
// injected via Spring
private InterfaceBP bpService;
public void setBpService(InterfaceBP bpService) {
this.bpService = bpService;
}
public TestVO getTestData(String testString) throws Exception {
BPRequestVO bpRequestVO = new BPRequestVO();
bpRequestVO.setGroupNumber(testString) ;
bpRequestVO.setProductType("ALL") ;
bpRequestVO.setProfileType("Required - TEST") ;
IBPServiceResponse serviceResponse = bpService.getProduct(bpRequestVO); //PROBLEM
if (serviceResponse.getMessage().equalsIgnoreCase("BOB")) {
throw new Exception();
} else {
TestVO testVO = new TestVO();
}
return testVO;
}
}
Spring配置:
<bean id="testClass" class="com.foo.TestClassFacade">
<property name="bpService" ref="bpService" />
</bean>
<bean id="bpService" class="class.cloud.BPService" />
Mockito测试方法:
@RunWith(MockitoJUnitRunner.class)
public class BaseTest {
@Mock BPService mockBPService;
@InjectMocks TestClassFacade mockTestClassFacade;
private String testString = null;
private BPRequestVO someBPRequestVO = new BPRequestVO();
private IBPServiceResponse invalidServiceResponse = new BPServiceResponse();
@Test (expected = Exception.class)
public void getBPData_bobStatusCode_shouldThrowException() throws Exception {
invalidServiceResponse.setMessage("BOB");
someBPRequestVO.setGroupNumber(null);
someBPRequestVO.setProductType("ALL");
someBPRequestVO.setProfileType("Required - TEST");
System.out.println("1: " + someBPRequestVO.getGroupNumber());
System.out.println("2: " + someBPRequestVO.getProductType());
System.out.println("3: " + someBPRequestVO.getProfileType());
System.out.println("4: " + someBPRequestVO.getEffectiveDate());
when(mockBPService.getProduct(someBPRequestVO)).thenReturn(invalidServiceResponse);
mockTestClassFacade.getTestData(testString);
verify(mockBPService).getProduct(someBPRequestVO);
}
}
系统输出:
1: null
2: ALL
3: Required - TEST
4: null
这里发生的事情是,当我运行测试时,serviceResponse对象在CUT标记为// PROBLEM的行上为空。我的愿望是用我的&#34; invalidServiceResponse&#34;填充该对象。来自我的测试方法的对象。从我的System.out.println的输出来看,我的bpRequestVO似乎与我的someBPRequestVO在内容中匹配。
有人可以告诉我我在这里失踪了吗?
谢谢你的时间!
答案 0 :(得分:9)
您与when()
一起使用的BPRequestVO实例与getTestData()
中使用的实例不同。
除非您覆盖equals()
,否则它们将无法匹配。
如果覆盖equals(),则不需要编写自定义匹配器。请注意Mockito documentation中的以下内容:
&#34;自定义参数匹配器可以降低测试的可读性。有时为传递给模拟的参数实现equals()会更好(Mockito自然地使用equals()进行参数匹配)。这可以使测试更清洁。&#34;
答案 1 :(得分:5)
问题在于您使用when()
。
您提交对构造实例的引用;因此,只有传递给方法的参数相同的引用时,模拟才会返回您想要的内容。
你想要的是一个论证匹配器;类似的东西:
when(mockBPService.getProduct(argThatMatches(someBPRequestVO))
.thenReturn(whatYouWant);
当然,它要求您编写参数匹配器!
请注意,内置匹配器可以执行您想要的操作:
when(mockBPService.getProduct(eq(someBPRequestVO))).thenReturn(whatYouWant);
此匹配器当然要求您的BPRequestVO
类实现equals()
(以及hashCode()
)!
答案 2 :(得分:3)
您可以使用“any(YourObject.class)”创建一个模拟参数,而不是在BPRequestVO类中创建一个equals方法:
when(mockBPService.getProduct(any(BPRequestVO.class))).thenReturn(invalidServiceResponse);
答案 3 :(得分:0)
用于模拟的BPRequestVO对象实例与junit执行时使用的实例不同。
最好的方法是在模拟时配置对象的任何实例
$flaglightgallery.on('onAfterAppendSubHtml.lg', function() {
// things you want to happen after triggering light gallery.
});
可以用
更新when(mockBPService.getProduct(someBPRequestVO)).thenReturn(invalidServiceResponse);
答案 4 :(得分:0)
我的问题是模拟服务被定义为 final。