如何在 junit 测试中 suppress/bypass 一个静态方法?

How to suppress/bypass a static method in a junit test?

假设我有以下代码:

protected int returnFourtyTwo() {
    evilMethod(new Object, "");
    return 42;
}

protected static void evilMethod(Object obj, String string) {
    throw new RuntimeException("This is me being evil.");
}

我想要做的是 运行 我的 returnFourtyTwo() 方法,而不在我的单元测试中抛出 运行time 异常。之前我已经能够使用 suppress() 方法绕过 class 构造函数,但这是我第一次不得不在非静态 class。不幸的是,关于该主题的资源有点稀缺。

您唯一的出路是模拟静态方法,如@Dave 所述。您可以使用 PowerMock 做到这一点。

Mocking static methods with Mockito

根据您的实际方法实现的复杂程度,您可以将 return 调用与异常抛出分开 - 然后测试不会抛出异常的 return 调用。在很多情况下,最好是 42 之类的奇怪整数无论如何都有自己的变量来解释它对应的内容 - 如果它是 always 42,那么它是静态的并且最终.

这就是我针对你的具体情况所做的,但我猜这是对你的实际问题的一个主要的简单抽象,所以你可能仍然想按照之前的建议模拟它。

static final int theAnswerToLife = 42;

protected int returnFourtyTwo() {
    evilMethod(new Object, "");
    return getTheAnswerToLife();
}

protected int getTheAnswerToLife() {
    return theAnswerToLife;
}

protected static void evilMethod(Object obj, String string) {
    throw new RuntimeException("This is me being evil.");
}

简单来说,您可以在您的方法中使用@Ignore 注释。

我不是说这是一个好方法,但至少它有效而且还不错。 你可以这样做:

  1. 在您的 inTest class 中创建一个 public 方法并将您的静态方法调用移动到那里
  2. 在你的单元测试中 - 你正在测试 inTest class - 你可以为你的 inTest [=51= 使用间谍而不是模拟]
  3. 只要求单元测试对该方法不做任何事情

缺点?我们有一个 public 方法而不是 private

示例: 我正在对 recyclerView 适配器进行单元测试:

我有一个记录器它有静态方法调用所以我将所有日志移到一个方法

    fun logMe(message: String) {
       MyCrashAnalytics.leaveBreadcrumb(message)
    }

在单元测试中我们有:

   val underTest = MyAdapter(....)

然后在测试或设置方法中我们可以做到这一点。

   val spiedUnderTest = spy(underTest)
   doNothing().`when`(spiedUnderTest).logMe(anyString())

那我们就可以开始了!