我使用的是Mockito 1.9.0。我该如何验证一个方法被调用了一次,并且传递给它的某个字段包含某个值?在我的JUnit测试中,我有
@Before
public void setupMainProg() {
// Initialize m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc
...
m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc);
} // setupMainProg
@Test
public void testItAll() throws GeneralSecurityException, IOException {
m_prog.work();
}
方法"work"调用一个方法"m_orderSvc"(传递给对象的参数之一)。"m_orderSvc"又包含一个成员字段"m_contractsDao"。我想验证"m_contractsDao.save"是否只被调用过一次,并且传递给它的参数是否包含某个值。
这可能有点令人困惑。让我知道如何澄清我的问题,我很乐意这样做。
首先需要创建一个mock m_contractsDao并进行设置。假设类是ContractsDao:
ContractsDao mock_contractsDao = mock(ContractsDao.class);
when(mock_contractsDao.save(any(String.class))).thenReturn("Some result");
然后将mock注入m_orderSvc并调用您的方法。
m_orderSvc.m_contractsDao = mock_contractsDao;
m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc);
m_prog.work();
最后,验证mock是否被正确调用:
verify(mock_contractsDao, times(1)).save("Parameter I'm expecting");
基于曼博金的答案:
ContractsDao mock_contractsDao = mock(ContractsDao.class);
when(mock_contractsDao.save(anyString())).thenReturn("Some result");
m_orderSvc.m_contractsDao = mock_contractsDao;
m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc);
m_prog.work();
针对验证参数是否包含特定值的请求,我可以假设您的意思是该参数是String,并且您想要测试String参数是否包含子字符串。为此,你可以做:
ArgumentCaptor<String> savedCaptor = ArgumentCaptor.forClass(String.class);
verify(mock_contractsDao).save(savedCaptor.capture());
assertTrue(savedCaptor.getValue().contains("substring I want to find");
如果这个假设是错误的,并且save()
的论点是某种集合,那么它只会略有不同:
ArgumentCaptor<Collection<MyType>> savedCaptor = ArgumentCaptor.forClass(Collection.class);
verify(mock_contractsDao).save(savedCaptor.capture());
assertTrue(savedCaptor.getValue().contains(someMyTypeElementToFindInCollection);
如果你知道如何使用Hamcrest匹配器,你也可以查看ArgumentMatchers。
这是更好的解决方案:
verify(mock_contractsDao, times(1)).save(Mockito.eq("Parameter I'm expecting"));