【问题标题】:Mock a static method that's inside a static method模拟静态方法中的静态方法
【发布时间】:2017-03-09 19:21:13
【问题描述】:

我有一个调用另一个静态方法 (bar) 的静态方法 (foo)。我想在我的测试中模拟 bar 的响应。这可以使用 PowerMockito 或其他工具吗?我能找到的唯一结果是在非静态方法中模拟静态。

public class SomeClass {
   static List<String> foo() {
      ...
      int barResult = bar();
      ...
   }

   static int bar() {
      // make a database call
      return DAO.getDao().runQuery();
   }
}

我的测试会这样称呼它:

@RunWith(PowerMockRunner.class)
public class SomeClassTest {

   @PrepareForTest(SomeClass.class)
   @Test
   public void fooTest() {
      List<String> actualResult = SomeClass.foo();
      assertTrue(...);
   }
}

我将不得不模拟 bar 的内部结构吗?所以嘲笑 DAO?

【问题讨论】:

  • 你不应该在没有充分理由的情况下使用静态方法。由于访问其他类中的静态方法而难以测试的代码也出于同样的原因难以重用
  • 感谢您的接受 :-)

标签: java unit-testing powermockito


【解决方案1】:

你不能那样做。

只有 PowerMock 允许您模拟静态方法。但这通过“擦除”该类中的所有静态事物来工作,这些事物“准备”以供 PowerMock 测试。

如果您谈论的是普通方法,您可能会选择 Mockito 间谍,因为它们允许部分模拟。

仅作记录:避免使用静态,因为使用它会导致“难以测试”的代码。

换句话说:与其使用又大又丑的 powermock 锤来“修复”您的设计问题...考虑改正您损坏的设计,从而完全避免使用 PowerMock!

为了记录:是的,您可以通过模拟 DAO 类上的静态调用来解决您的问题(然后您可以控制 bar() 间接执行的操作。但同样:这只是意味着将“我测试过" 代码上的标签应该被改写。

【讨论】:

  • 如果您使用具有静态方法的外部类怎么办?用它们创建包装器?
  • @Alessandroempire 这取决于您使用它们的频率。请记住:当您在自己的代码中直接调用这些外部静态方法时……您正在向这些类引入紧密耦合。因此,当您决定有一天切换库时 - 您将不得不更新所有使用该静态调用的类。从这个意义上说:像往常一样,这是关于平衡。
【解决方案2】:

你可以这样做:

@RunWith(PowerMockRunner.class)
@PrepareForTest({SomeClass.class, DAO.class})
public class SomeClassTest {

   @Test
   public void fooTest() {
      PowerMockito.mockStatic(DAO.class);
      Mockito.when(DAO.getDao().runQuery()).return(..);
      List<String> actualResult = SomeClass.foo();
      assertTrue(...);
   }
}

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多