我有一个带有一些复杂逻辑的类,所以我决定多次使用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
在这些情况下通常会做什么?
答案 0 :(得分:1)
在考虑单元测试时,你会做你经常做的事情:
它告诉你:你的“方法类”(我宁愿称它们为“服务类”)需要进行密集的单元测试;确保他们提供的“服务”实际上已经交付。
对于MapperClass,理论上可以重复使用这些测试用例;因为“真正公开”的合同可能与MapperClass有关。
但当然:这意味着“代码重复”;如果你考虑一下:MapperClass只需要“某种”管道测试“。含义:您只需需要来测试是否正确调用了这些方法类以提供所需的结果。您不需要针对MapperClass运行所有您的测试。
当避免在MapperClass中的方法中调用new
时(例如通过将方法对象转换为字段,并使用构造函数伸缩和依赖注入),您甚至可以使用模拟框架来简单地检查:当我称之为“外部”方法;调用正确的方法对象。
但有一点需要注意:当你没有为MapperClass提供完整的“合同检查”套件时,你后来决定再次重构,那么你就会“破碎”。因为所有合同检查测试代码都“附加”到特定的“方法类”。因此,您必须将所有这些测试移至“MapperClass范围”。所以你应该有意识地做出这个决定(但我仍然主张不重复测试代码;并且去寻找上面提到的解决方案 - 但是你应该理解这个决定的重要结果。)