java - 具有多个方法对象的测试类

标签 java unit-testing testing refactoring

我有一个包含一些复杂逻辑的类,所以我决定使用 method object多次重构它。

假设有一个像下一个这样的类:

public class MapperClass {

    Entity entity = new Entity(); 
    private final Item item;

    public MapperClass(Item item) {
       this.item = item;
    }

    public Entity getEntity() {
          entity.setPrice(extractPrice());
         //more long and complicated implementation
         //mapped from item values
         //entity.set....
         //...
         return entity;
    }

    private double extractPrice() {
        double priceExtracted = 0d;
        //Long and complicated implementation
        //extracted from item
        //...
        return priceExtracted ;
    }

    private List<SubItem> getSubItemsMapped() {
       //Long and complicated implementation
       //extracted from item
       //...
    }

}

我将其重构为:

 public class MapperClass{

    private Entity entity = new Entity(); 
    private final Item item;

    public MapperClass(Item item) {
       this.item = item;
    }

    public Entity getEntity() {
          entity.setPrice(extractPrice());
          entity.setSubEntities(getSubItemsMapped());
         //more long and complicated implementation
         //mapped from item values
         //entity.set....
         //...
         return entity;
    }

    private double extractPrice() {
        new PriceCalculator(item).getPrice();
    }

    private List<SubItem> getSubItemsMapped() {
       new SubItemsMapper(item).getSubItems();
    }

   //More similar cases
}

然后我就有了一个包含多个方法对象的类,它比一个复杂的类更干净。

然后当我去做我的测试时,我对如何测试这个类产生了疑问。

method object 测试类的最佳方法是什么? ?

  • 只用方法对象测试类
  • 独立测试所有类、方法对象类,然后深入测试带有方法对象的类
  • 测试所有类,但深入方法对象类,以及带有简单类的方法对象类以检查它至少被此方法对象映射.
  • 它的设计很糟糕,因此请重新考虑如何设计它,然后再进行测试。
  • 其他选项。

在这些情况下通常会做什么?

最佳答案

在考虑单元测试时,您会做您经常做的事情:

  • 您查看类 X 公开的公共(public) 接口(interface)。含义:将在该类的对象上调用哪些方法;参数是什么;每种方法的契约是什么。
  • 您编写的测试用例完全涵盖了每个方法的约定。

这告诉您:您的“方法类”(我宁愿称它们为“服务类”)需要进行密集的单元测试;以确保他们提供的“服务”……真正交付。

对于您的 MapperClass,理论上您可以重复使用这些测试用例;因为“真正公开”的契约(Contract)可能与那个 MapperClass 相关。

但当然:那将意味着“代码重复”;如果您考虑一下:MapperClass 只“需要”某种“管道测试”。意思是:您只需要测试那些方法类是否被正确调用以提供所需的结果。您不需要针对 MapperClass 运行所有测试。

如果避免在 MapperClass 的方法中调用 new(例如,通过将方法对象转换为字段,并使用构造函数伸缩和依赖注入(inject)),那么您甚至可以使用模拟框架来只需检查:当我调用“外部”方法时;正确的方法对象被调用。

但有一个警告:如果您没有 MapperClass 的完整“契约(Contract)检查”套件,而您后来又决定再次重构,那么您就“崩溃了”。因为所有契约(Contract)检查测试代码都“附加”到特定的“方法类”。因此,您必须将所有这些测试移动到“MapperClass 范围”。因此,您应该有意识地做出该决定(但我仍然提倡不要复制测试代码;并寻求上述解决方案 - 但您应该了解该决定的重要后果)。

关于java - 具有多个方法对象的测试类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43776276/

相关文章:

c# - XUnit.net 在运行后立即捕获每个测试的结果

testing - Angular e2e 测试 - 未捕获的 ReferenceError : inject is not defined

php - 如何制作 PHP 测试套件

java - 内部类上的 Android 数据绑定(bind)不更新 TextView

python - 从 Python 的子目录运行所有测试

ruby-on-rails - 在文件中存储测试数据的最佳格式是什么?

ios - 使用模拟器测试自定义位置

Java 防止返回 null

java - JVM 能否优化引用 null(null 类型的实例)所需的内存?

java - 等待共享资源的线程