我是Mockito的新手。我正在使用Mockito为一个班级编写测试。我有一个调用同一类的其他方法的方法。我该如何嘲笑这种方法?我已经发布了我正在尝试为其编写测试的类。我正在尝试模拟方法过程(PersonDTO person)
public class Processor {
@Autowired
private SomeService service;
@Autowired
private SomeServiceProperties properties;
private Util util = new Util();
public SPMOutboundVO process(PersonDTO person) throws Exception {
SPMOutboundVO outboundVO = null;
if(validatePersonForBenefitsProcessing(person)) {
PersonPayrollFromWorkdayVO personPayrollFromWorkdayVO = service.getPersonPayrollFromWorkday(util.getStartOrEndDate(DayOfWeek.SUNDAY),util.getStartOrEndDate(DayOfWeek.SATURDAY),person.getEmployeeID());
if(personPayrollFromWorkdayVO != null) {
person.setBillingStartDate(getPayrollPeriod(personPayrollFromWorkdayVO));
person.setAmount(util.getMonthlyDiscountPayRate(person.getPayPeriod(),getDiscountRate(personPayrollFromWorkdayVO)));
}
if(isNewLeave(person,getPayrollPeriod(personPayrollFromWorkdayVO))) {
person.setBillingStartDate(getPayrollPeriod(personPayrollFromWorkdayVO));
outboundVO = processOutboundSPMInsertRecords(person);
} else if (person.isReturnFromLeaveOrTermed()){
person.setBillingEndDate(person.getFirstDayBackAtWorkMinus1());
outboundVO = processOutboundSPMUpdateRecords(person);
}
}
return outboundVO;
}
public boolean validatePersonForBenefitsProcessing(PersonDTO person) {
// Some code
}
public SPMOutboundVO processOutboundSPMInsertRecords(PersonDTO person) {
// Some code
}
public SPMOutboundVO processOutboundSPMUpdateRecords(PersonDTO person) {
// Some code
}
public String getPayrollPeriod(PersonPayrollFromWorkdayVO personPayrollFromWorkdayVO) {
// Some code
}
public boolean isNewLeave(PersonDTO, String) {
// Some code
}
}
首先,从技术上讲,您可以使用 mockito 模拟类中的选定方法。 此功能称为部分模拟。 在模拟文档中进行了解释:https://static.javadoc.io/org.mockito/mockito-core/3.0.0/org/mockito/Mockito.html#partial_mocks。
第二:在某些情况下,在测试一个类时模拟同一类中的其他方法是有意义的。 一个很好的例子是将交互与其他组件捆绑在一起的方法(为了示例,我们称之为do_interactions
),这样类的其余方法就没有这种交互,并且只为此目的调用do_interactions
。 更具体地说,考虑一个为其他方法提供文件内容的方法:它捆绑了与操作系统的交互,如打开和阅读,并只返回内容。 然后,您可以轻松地独立于操作系统执行测试,只需模拟该函数,让它在测试需要时返回"简化"文件内容。
也就是说,有一些例子表明这种嘲笑是有意义的,但这不一定适用于你的情况。
第三,测试是关于发现错误(参见Myers,Badgett,Sandler:软件测试的艺术,或Beizer:软件测试技术等),单元测试旨在发现那些可以在隔离代码中找到的错误。 为了有效地查找错误,您必须进行特定于实现的测试:错误在实现中,不同的实现具有不同的错误。 想想大量的排序算法:它们都有相同的API,但它们的实现完全不同。 或者,考虑实现斐波那契函数的方法:作为迭代或递归函数,作为封闭形式表达式(Moivre/Binet)或查找表。 同样,界面总是相同的,可能的错误差异很大,单元测试策略也是如此。 而且,单元测试是最接近实现级别的测试级别 - 集成测试,子系统测试和系统测试更高,因此不太适合在实现中发现错误。 因此,尝试在单元测试中保持与实现无关可能会导致测试套件效率降低。
也就是说,您确实也应该努力减少测试维护工作量。 这意味着,如果该特定测试不需要测试用例实现,请不要将其指定为特定。 并且,对于那些有充分理由特定于实现的测试,仍然尝试保持较低的维护工作量,例如通过在帮助程序方法中提取测试的实现特定部分,以减少在更改 SUT 时必须维护的测试代码量(请参阅 [Meszaros:测试自动化原理: 确保相应的努力])。