java - 如何模拟调用同一类中存在的其他方法的方法

标签 java unit-testing spring-boot mockito spring-batch

我是 Mockito 的新手。我正在使用 Mockito 为一个类编写测试。我有一个方法可以调用同一类的其他方法。我将如何 mock 这个方法?我已经发布了我正在尝试为其编写测试的类(class)。我正在尝试模拟方法过程(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模拟类中选定的方法。此功能称为部分模拟。在mockito文档中对此进行了解释:https://static.javadoc.io/org.mockito/mockito-core/3.0.0/org/mockito/Mockito.html#partial_mocks .

第二:在某些情况下,在测试一个类以模拟同一类中的其他方法时是有意义的。一个很好的例子是一个捆绑与其他组件交互的方法(为了举例,我们将其称为do_interactions),这样该类的其余方法就不受此类交互的影响,并且仅出于此目的调用do_interactions。更具体地说,考虑一种为其他方法提供文件内容的方法:它将与操作系统的交互(例如打开和读取)捆绑在一起,并且只返回内容。然后,您可以轻松地独立于操作系统执行测试,只需模拟该函数,让它在测试需要时返回“模拟”文件内容。

也就是说,有一些例子表明这种 mock 是有意义的,但这不一定适用于您的情况。

第三,测试是为了发现错误(参见 Myers、Badgett、Sandler:软件测试的艺术,或者 Beizer:软件测试技术,等等),单元测试的目的是发现那些可以在独立代码中找到的错误。为了有效地发现错误,您必须进行特定于实现的测试:错误存在于实现中,不同的实现有不同的错误。想想大量的排序算法:它们都有相同的 API,但它们的实现却完全不同。或者,考虑实现斐波那契函数的方法:作为迭代或递归函数、作为封闭形式表达式(Moivre/Binet)或作为查找表。同样,界面总是相同的,可能的错误显着不同,单元测试策略也是如此。而且,单元测试是最接近实现级别的测试级别 - 集成测试、子系统测试和系统测试都处于较高水平,因此不太适合发现实现中的错误。因此,尝试在单元测试中保持实现不可知可能会导致测试套件效率降低。

也就是说,您确实还应该努力降低测试维护工作量。这意味着,如果特定测试没有必要,则不要指定特定的测试用例实现。而且,对于那些有充分理由特定于实现的测试,仍然尝试保持较低的维护工作量,例如通过在辅助方法中提取测试的特定于实现的部分,以减少在 SUT 发生更改时必须维护的测试代码量(请参阅 [ Meszaros: Principles of Test Automation: Ensure Commensurate Effort ])。

关于java - 如何模拟调用同一类中存在的其他方法的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57235607/

相关文章:

unit-testing - 暂停可取消协程取消的 Kotlin Mockk 测试

java - 如何获取要保存到 MDC 的请求 header

java - Tomcat 日志压缩和旋转

java - Java 是运行每个条件运算符还是在 If 语句中短路?

maven - Maven生命周期错误阶段发生的Grails单元测试

java - 将单独的 java 应用程序集成为单个应用程序的模块

java - 未找到测试 - 在准系统 Spring Boot Maven 项目上运行 jUnit 5 测试用例时出现空测试套件

java - 如何在 jar 文件上远程执行方法

java - 将 JSON(或对象)添加到 STRING json 数组

unit-testing - 使用 Jest 模拟的服务会导致 "The module factory of jest.mock() is not allowed to reference any out-of-scope variables"错误