1 回答
TA贡献1799条经验 获得超8个赞
像往常一样,单元测试迫使您考虑类的设计。
首先,您应该注意到您有两种主要的不同类型的对象。
有些对象是值:它们是不可变的,可以存在于多个副本中,是可比较的(并且hashCode
也有一个)。这是一种易于存储在数据库中的对象。如果您对 Kotlin 有所了解,您就会听说过data classes
: 就是这样。
其他一些具有实体语义的对象:它们是可变的,比较它们没有意义,而且通常只有它们的一个副本。它们是做某事的对象。
具有实体语义的对象是您需要在单元测试中模拟的对象,而您不需要模拟值。为了传递模拟,这些对象必须作为构造函数的参数注入到类中。
在您的代码片段中,您在函数中创建了一个对象,该对象似乎具有实体的语义(值什么都没有finish
),这就是您遇到问题的原因:您无法进行单元测试,因为您无法模拟该实体.
解决方案很简单:要么在方法中注入对象:
public interface ISomeInterface
{
default Integer callMe(Object someObject)
{
Integer result = someObject.finish();
result = result + 1;
return result;
}
...
}
或者你在类中注入对象:
public interface ISomeInterface
{
default Integer callMe()
{
Integer result = finishObject();
result = result + 1;
return result;
}
// classes will need an instance of the object to implement this
Integer finishObject();
...
}
在这两种情况下,实现您的接口的类要么负责在调用方法时提供对象本身,要么负责返回方法的值finish。
但请记住:如果您在这些类的方法中创建对象,对它们进行单元测试也会变得困难。使用工厂模式在静态方法中创建实体对象并将这些对象传递给构造函数。
如果遵循这条经验法则,类和方法的单元测试将变得更容易:当对象具有语义值时,在更高级别创建它(如果可能)并将其作为构造函数或方法的参数main传递。
添加回答
举报