测试类有几个方法对象

时间:2017-05-04 07:16:07

标签: java unit-testing testing refactoring

我有一个带有一些复杂逻辑的类,所以我决定多次使用rename parameter来重构它。

假设像下一个类:

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 objects的课程比一个复杂的课程更清晰。

然后当我去做我的测试时,我怀疑如何测试这个课程。

使用method object测试课程的最佳方式是哪种?

  • 仅使用method objects
  • 测试班级
  • 独立测试所有类,方法对象类,然后全部测试类和方法对象
  • 测试所有类,但方法对象类深入,带有方法对象的用简单的类检查它至少由此方法对象映射
  • 它有一个糟糕的设计,所以重新考虑如何设计它,然后进行测试。
  • 其他选择。

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

1 个答案:

答案 0 :(得分:1)

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

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

它告诉你:你的“方法类”(我宁愿称它们为“服务类”)需要进行密集的单元测试;确保他们提供的“服务”实际上已经交付。

对于MapperClass,理论上可以重复使用这些测试用例;因为“真正公开”的合同可能与MapperClass有关。

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

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

但有一点需要注意:当你没有为MapperClass提供完整的“合同检查”套件时,你后来决定再次重构,那么你就会“破碎”。因为所有合同检查测试代码都“附加”到特定的“方法类”。因此,您必须将所有这些测试移至“MapperClass范围”。所以你应该有意识地做出这个决定(但我仍然主张重复测试代码;并且去寻找上面提到的解决方案 - 但是你应该理解这个决定的重要结果。)