使用Mockito,我如何验证一个方法是用某个参数调用的?

2022-08-31 14:21:49

我使用的是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”是否被调用了一次,并且传递给它的参数包含某个值。

这可能有点令人困惑。让我知道我如何澄清我的问题,我很乐意这样做。


答案 1

首先,您需要创建一个模拟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(); 

最后,验证是否正确调用了模拟:

verify(mock_contractsDao, times(1)).save("Parameter I'm expecting");

答案 2

根据Mamboking的答案构建:

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

你也可以看看ArgumentMatchers,如果你知道如何使用Hamcrest matchers。


推荐