繁体   English   中英

如何测试依赖于另一个已测试方法的方法?

[英]How to test a method that depends on another already tested method?

我正在研究一种方法,可以将其视为另一种已定义和测试的方法的特化。 这是一个示例代码来说明:

public class ProductService {

    public void addProduct(Product product) {
        //do something
    }

    public void addSpecialProduct(Product product) {
        addProduct(product);
        //do something after
    }

}

我不想复制我对addProduct的测试,这些测试已经非常复杂了。 我想要的是当我为addSpecialProduct定义测试时,我只是确保它也在进程中调用addProduct 如果这是2个类协作的问题,那么很容易让协作者进行模拟并且只是验证目标方法是否被调用(并在必要时存根)。 但是,这两种方法属于同一类。

我现在想的是监视我正在测试的对象,例如:

public void testAddSpecialProduct() {
    //set up code
    ProductService service = spy(new DefaultProductService());    
    service.addSpecialProduct(specialProduct);
    verify(service).addProduct(specialProduct);
    //more tests
}

但是,我想知道这种方法是否会以某种方式违背单元测试的目的。 关于这件事的一般共识是什么?

我认为这取决于您希望单元测试的严谨程度。 在极端意义上,单元测试应该只测试行为,而不是实现。 这意味着你需要复制你的测试(或者采取@chrylis的建议,将常用功能抽象给帮助者)。 确保调用其他方法是测试实现。

但实际上,我认为你在实例上监视间谍以确保调用其他经过良好测试的方法的想法是个好主意。 这是我的理由:

1)它简化了您的代码。

2)我立即清楚地知道发生了什么。 它告诉我,为其他方法测试的所有东西现在也都是真的,这里是额外的断言。

有一天,您可以修改实现,以便不调用其他方法,这将导致您的单元测试失败,这是人们通常试图通过不测试实现来避免的。 但根据我的经验,当行为发生变化时,这样的变化会更加常见。

您可以考虑重构代码。 使用策略模式实际实现添加产品和特殊产品的功能。

public class ProductService {

    @Resource
    private AddProductStrategy normalAddProductStrategy;
    @Resource
    private AddProductStrategy addSpecialProductStrategy;

    public void addProduct(Product product) {
        normalAddProductStrategy.addProduct(product);
    }

    public void addSpecialProduct(Product product) {
        addSpecialProductStrategy.addProduct(product);
    }
}

AddProductStrategy将有2个实现。 一个人就是在原始的ProductService.addProduct实现中发生的事情。 第二个实现将委托给第一个实现,然后执行所需的额外工作。 因此,您可以单独测试每个策略。 第二个策略实现只是第一个实现的装饰器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM