如何从 class 实例到达模拟的静态方法

How to reach to static method from class instance for mock

我需要存根 Java.util.concurrent.Executors class newFixedThreadPool 方法并验证它。

    Executors.newFixedThreadPool(executorServiceThreadCount, threadFactory)

我尝试创建一个全局 Executors 值以覆盖测试片段。

    lazy val executors = Executors

但是无法从执行程序实例访问 newFixedThreadPool 方法。 我应该怎么做才能存根这个方法。对此有什么最佳做法吗?谢谢

您可以使用 PowerMockito 模拟静态方法。在测试 class:

之上使用以下注释

@RunWith(PowerMockRunner.class) @PrepareForTest({Executors.class, ClassYouAreTesting.class})

并使用以下代码模拟 newFixedThreadPool 方法:

PowerMockito.mockStatic(Executors.class); Mockito.when(Executors.newFixedThreadPool(5)).thenReturn(mockService);

newFixedThreadPool 方法可能已经过测试,所以我不会花太多时间来测试它。

相反,我假设您实际尝试做的是测试使用 newFixedThreadPool return 类型 (ExecutorService) 的 class。 如果是这种情况,那么您有多种选择:

  1. 使用依赖注入并创建集成测试样式 - 你可以做的是将 ExecutorService 传递给你的 class 被测(你可以使用构造函数或 setter。我通常将它传递给构造函数,但这是一个完全不同的主题),然后传递一个 ExecutorService 模拟。 我得说,过去我尝试模拟 ExecutorService 代码,但不是很有趣。这种方法的优点是您还可以测试线程之间的交互,从而测试更能反映真实场景的场景。
  2. 更多的单元测试方法是测试线程池中的线程调用的代码(您即将 运行 的 callable/runnable 代码)。这更容易编写,而且绝对更孤立。这里的缺点是您没有测试线程之间的所有交互。

我应该补充的几件事:

  • 我倾向于不喜欢所有这些允许你做一些魔术(比如模拟静态方法等)的强大工具,不是因为它们不够强大,而是因为它只是觉得如果你需要那么多的力量只是测试一些东西然后你的设计可能有问题
  • 我有意回避了一些热门话题,例如 setter/constructor 注入和 integration/unit 测试,因为我觉得它超出了范围
  • 我通常会尽量避免(如果可能的话)在我的线程之间共享资源,所以我不会从采用更多集成风格的方法中获益太多(在这些情况下)

希望对您有所帮助:)