【问题标题】:How to reach to static method from class instance for mock如何从类实例访问静态方法以进行模拟
【发布时间】:2016-03-10 09:41:16
【问题描述】:

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

    Executors.newFixedThreadPool(executorServiceThreadCount, threadFactory)

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

    lazy val executors = Executors

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

【问题讨论】:

  • 简短回答:你不能。静态方法是全局的,并且一劳永逸地定义,您不能覆盖它们。您可以尝试定义一个新特征,该特征将转发到Executors 的方法并在您的所有代码中使用它。然后你可以“存根”这个特征。

标签: scala unit-testing mockito scalatest


【解决方案1】:

您可以使用 PowerMockito 模拟静态方法。在您的测试类之上使用以下注释:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    我应该补充几点:

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

    我希望这会有所帮助:)

    【讨论】:

    • 他没有尝试测试newFixedThreadPool。这就是他试图嘲笑它的原因。
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 2023-03-08
    • 2016-02-25
    • 2016-11-10
    • 2020-07-09
    • 2013-06-06
    • 1970-01-01
    • 2018-12-23
    相关资源
    最近更新 更多