【问题标题】:How do I test Java code that uses JAR?如何测试使用 JAR 的 Java 代码?
【发布时间】:2016-08-05 00:07:10
【问题描述】:

我有使用 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 文件。

由于还没有 JAR 文件,它在生产构建(在 Gradle 中)失败。

【问题讨论】:

  • 你在测试什么?如果您正在测试此方法的客户端,请连接包含类或它实现的接口的适当模拟。如果您正在测试该方法的实现,您可以验证它是否为 null 或与预期模式匹配。如果您正在测试 getImplementationVersion() 本身,请停止 - 它可能是带有自己测试的第三方代码。

标签: java eclipse gradle junit jar


【解决方案1】:

您总是需要模拟依赖项以进行单元测试。边界是单元测试您的代码,而不是 jar 本身。 Mockito 框架很好,还有其他框架可以完成这项工作。

【讨论】:

    【解决方案2】:

    可能无法正确模拟(因此:未进行单元测试)。关键是您实际上是在“this”上调用一个方法。但是你不能测试一些对象......同时模拟它。

    你看,如果你的生产代码看起来像这样:

    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....
    

    现在您可以使用依赖注入来提供返回该字符串的“模拟”包。但是,看起来很多代码几乎没有任何收获。

    长话短说:有时,您根本无法编写合理的单元测试。然后做下一件最好的事情:创建一些在“客户喜欢”设置中自动执行的“功能”测试;并确保您也有一个自动设置来运行此类测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多