我有使用JAR的Java代码:
public class Version {
public String getVersion() {
// Use Java Package API to return information specified in the manifest of this JAR.
return getClass().getPackage().getImplementationVersion();
}
}
如何为此代码运行JUnit测试?
它在开发构建(在Eclipse中)失败,因为还没有JAR文件。
它在生产版本中失败(在Gradle中),因为还没有JAR文件。
答案 0 :(得分:1)
您始终需要模拟单元测试的依赖项。边界是单元测试您的代码而不是jar本身。 Mockito框架很好,还有其他框架可以完成这项工作。
答案 1 :(得分:1)
可能无法正确模拟(因此:未进行单元测试)。关键是你实际上是在"这"上调用一个方法。但你无法测试某些物体......并同时嘲笑它。
如果您的生产代码如下所示:
public String getVersion() {
return someObject.getClass().....
}
然后你可以创建一个模拟对象;并将其插入到您的Version类中。但即使这样,方法getClass()在java.lang.Object中也是 final ;因此无论如何你都无法嘲笑它。
[合理的模拟框架,如EasyMock或Mokito通过扩展类和覆盖您想要控制的方法来工作。像PowerMock这样的框架可以进行字节代码操作并允许这种模拟 - 但是你永远不应该使用这样的库;因为它们有非常糟糕的副作用(比如打破大多数覆盖库)]
可能有用:
class Version {
private final Package packageForVersionCheck;
public Version() {
this(getClass().getPackage()));
}
Version(Package somePackage) {
this.packageForVersionCheck = ...
}
public String getVersion() {
return this.packageForVersionCheck.getImpl....
现在你可以使用依赖注入来提供一个" mocked"返回该字符串的包。但是,这看起来像很多代码几乎没有收获。
长话短说:有时,你根本无法写出合理的单元测试。然后做下一个最好的事情:创建一些"功能"在"客户中自动执行的测试,例如"建立;并确保您有自动设置来运行此类测试。