当前位置: 首页 > 面试题库 >

用Java模拟静态块

伊羽
2023-03-14
问题内容

我对Java的座右铭是“仅仅因为Java具有静态块,并不意味着您应该使用它们。”
除了笑话,Java中还有许多使测试成为噩梦的技巧。我最讨厌的两个是匿名类和静态块。我们有很多使用静态块的遗留代码,这些是我们编写单元测试时最讨厌的点之一。我们的目标是能够以最小的代码更改为依赖于此静态初始化的类编写单元测试。

到目前为止,我对同事的建议是将静态块的主体移到私有的静态方法中并对其进行调用staticInit。然后可以从静态块中调用此方法。对于单元测试,可以staticInit使用JMockit轻松模拟依赖于该类的另一个类,而不执行任何操作。让我们在示例中看一下。

public class ClassWithStaticInit {
  static {
    System.out.println("static initializer.");
  }
}

将更改为

public class ClassWithStaticInit {
  static {
    staticInit();
  }

  private static void staticInit() {
    System.out.println("static initialized.");
  }
}

这样我们就可以在JUnit中执行以下操作。

public class DependentClassTest {
  public static class MockClassWithStaticInit {
    public static void staticInit() {
    }
  }

  @BeforeClass
  public static void setUpBeforeClass() {
    Mockit.redefineMethods(ClassWithStaticInit.class, MockClassWithStaticInit.class);
  }
}

但是,该解决方案也有其自身的问题。您不能在同一JVM上运行DependentClassTestClassWithStaticInitTest因为您实际上希望为它运行静态块ClassWithStaticInitTest

您将如何完成此任务?还是您认为任何更好的,非基于JMockit的解决方案更干净?


问题答案:

遇到此问题时,我通常会执行与您描述的相同的操作,除了将静态方法设置为受保护的方法之外,以便可以手动调用它。最重要的是,我确保可以多次调用该方法而不会出现问题(否则就测试而言,它并不比静态初始化程序好)。

这工作得相当好,我可以实际测试静态初始化方法是否达到了我期望/想要的方式。有时,拥有一些静态初始化代码是最容易的,而构建一个过于复杂的系统来替换它是不值得的。

使用此机制时,请确保记录该受保护的方法仅出于测试目的而公开,并希望其他开发人员不会使用它。当然,这可能不是一个可行的解决方案,例如,如果类的接口在外部可见(作为其他团队的某种子组件,或者作为公共框架)。不过,这是解决问题的简单方法,不需要第三方库来建立(我喜欢)。



 类似资料:
  • 问题内容: 我已经写了一家工厂来生产物体: 我想验证传递给的参数,但不知道如何模拟静态方法。我在测试用例中使用的是和。有没有模拟或验证此特定用例的好方法? 问题答案: 在Mockito上使用PowerMockito。 示例代码:

  • 例如,我有以下课程: 我有一个类使用她的方法: 测试等级: 尝试运行测试时遇到的错误: 组织。莫基托。例外情况。基础MockitoException:对于TesteStatico,静态模拟已在当前线程中注册以创建新的模拟,必须取消注册现有的静态模拟注册 项目中LIB的版本: junit-jupiter 5.5.2 mockito-junit-jupiter 3.2.14 mockito-内联3.2

  • 在安装到AEM 5.6.1实例之前,我正在使用maven构建和测试我的代码。我已经编写了单元测试,这些测试使用wcm的实现从aem模拟中获益。io和其他需要使用powermockito模拟静态方法的单元测试。 以下是我对aem上下文、sling Mock和powermock的maven依赖关系。 在我的课堂上,我正在为aem上下文设置规则,并准备一些用于模拟的静态类: 当我通过命令行运行mvn测试

  • 我有一堂这样的课: 我需要使用EasyMock模拟服务<代码>EasyMock。createMock()后跟replay()不起作用。P、 S:这是其他开发人员编写的遗留代码,我们不能在这里更改代码。

  • 我正在使用cucumber BDD,testng,java编写一些BDD测试。为了编写我的测试,我想模拟静态类。然而,当我编写这个testrunner时,它无法初始化BDD场景。 这样做的一个副作用是,我无法在编写BDD时模拟util类的静态方法。我对cucumberBDD是新手。任何帮助/指针都是感激的。

  • 问题内容: 我的代码中有一个静态方法,希望以某种方式进行模拟。 我正在使用jmock。 我想可以做到这一点的一种方法是在静态方法周围设置“包装类”并模拟该方法,但是我希望有一个更好的解决方案。 我要用这种错误的方式? 反馈: 我将要有一个接口和一个类,该接口和类具有一个仅称为静态方法的方法。这将允许我通过仅模拟对此包装器类的调用来模拟逻辑。(即使谈论它我也觉得很脏:)) 问题答案: 我们不支持在j