【问题标题】:How to mock static reference in junit?如何在junit中模拟静态引用?
【发布时间】:2018-04-04 03:36:45
【问题描述】:

我在模拟项目中的静态成员时遇到问题。 请在下面找到与我的项目代码类似的示例。

class A {
private String place = null;
    public methodA() {
    this.place = LoadPlaceDao.placeDao.PlaceMap();
    .........
    .........
    .........

    }
}

public class LoadPlaceDao {
public static PlaceDao placeDao;

public LoadPlaceDao() {
    placeDao = new PlaceDaoImpl();
    }
} 

我的测试的主要目标只是代码覆盖率, 我正在尝试模拟 LoadPlaceDao.placeDao.PlaceMap(); 在 LoadPlaceDao.placeDao 附近获取 NullPointerException,因此剩余的行不会被覆盖。 PowerMockito 仅适用于静态方法。 **placeDao 是静态引用。

【问题讨论】:

  • 那么你几乎肯定做错了。在这种情况下,您显然做错了,因为您的构造函数正在覆盖一个静态字段,该字段是公共的而不是最终的。也许为您的用例提供更多背景信息。

标签: java spring junit mockito powermockito


【解决方案1】:

PowerMock 是一个 JUnit 扩展,它利用 EasyMock 和 Mockito 的可能性来模拟静态方法(以及更多)。

我们的测试单元是类 Calculator,它只是将两个整数的加法委托给仅提供静态方法的 MathUtil:

public class Calculator {

   public int add(int a, int b) {
      return MathUtil.addInteger(a, b);
   }
}

public abstract class MathUtil {

   public static final int addInteger(int a, int b) {
      return a + b;
   }

   private MathUtil() {}
}

出于某种模糊的原因,我们想要模拟 MathUtil,因为在我们的测试场景中,添加应该会产生与通常情况不同的结果(在现实生活中,我们可能会模拟 Web 服务调用或数据库访问)。怎么可能

his be achieved? Have a look at the following test:

@RunWith(PowerMockRunner.class)
@PrepareForTest( MathUtil.class )
public class CalculatorTest {

   /** Unit under test. */
   private Calculator calc;

   @Before public void setUp() {
      calc = new Calculator();

      PowerMockito.mockStatic(MathUtil.class);
      PowerMockito.when(MathUtil.addInteger(1, 1)).thenReturn(0);
      PowerMockito.when(MathUtil.addInteger(2, 2)).thenReturn(1);
   }

   @Test public void shouldCalculateInAStrangeWay() {
      assertEquals(0, calc.add(1, 1) );
      assertEquals(1, calc.add(2, 2) );
   }
}

首先,我们使用 PowerMock 框架提供的特殊测试运行器。使用@PrepareForTest(MathUtil.class) 注释,我们准备模拟的类。这个注解需要一个所有要模拟的类的列表。在我们的示例中,此列表由单个项目 MathUtil.class 组成。

在我们的设置方法中,我们调用 PowerMockito.mockStatic(...)。 (我们可以为 mockStatic 方法编写静态导入,但这样您可以更清楚地看到这些方法的来源。)

然后我们定义我们的模拟行为调用 PowerMockito.when(...)。在我们的测试中,我们有通常的断言。

【讨论】:

  • 感谢 Ajay,但是否有可能模拟静态引用,如果您在我的问题中看到我需要模拟静态引用,以便我可以覆盖剩余的行。 PowerMockito 仅适用于静态方法。我假设 mock 仅适用于非最终和私有的方法。原始类型也不支持。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 2011-06-21
  • 1970-01-01
相关资源
最近更新 更多