使用 Mockito 和 JUnit 模拟静态方法时出现 StackOverflowError

问题描述 投票:0回答:1

我正在使用 Mockito 练习 JUnit,并尝试测试一个简单的静态方法

class LessSimpleCalculatorImp implements LessSimpleCalculator {
    @Override
    public int power(int x, int y) {
        return (int)Math.pow(x, y); // <-- try to see if Math.pow has been called
    }
}

测试用例:

@RunWith(MockitoJUnitRunner.class)
public class LessSimpleCalculator_Test {
    @Test
    public void test_pow() {
        try(MockedStatic<Math> mockedMath = Mockito.mockStatic(Math.class);) {
            mockedMath.when(() -> Math.pow(3, 2)).thenReturn(9.0);
            int result = lessSimpleCalculator.power(3, 2);
            assertEquals(9, result);
            mockedMath.verify(() -> Math.pow(3, 2), times(1));
        }
    }
}

当我这样做时,这会给我一个 StackOverflowError

mvn clean test

Exception: java.lang.StackOverflowError thrown from the UncaughtExceptionHandler in thread "main"

ChatGPT 说这是因为模拟类调用了 Math.pow,它被模拟类拦截,再次调用真实类。我该如何解决这个问题?

我还使用 Maven 进行依赖管理:

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-junit-jupiter</artifactId>
      <version>5.13.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
java junit static mockito stack-overflow
1个回答
2
投票

这似乎是 Mockito 中的一个已知问题,他们不会修复它: https://github.com/mockito/mockito/issues/2105

老实说,无论如何,嘲笑

Math.pow
可以说是一种不好的方法,因为这意味着您的测试需要对
LessSimpleCalculatorImp
的实现有深入的了解。
在合约测试中,您不应该关心
LessSimpleCalculatorImp
的实现,而只关心最终结果 - 您已经知道 3 的 2 次方结果应该是 9(您已经将其作为预期结果)断言!),所以只需测试一下:

@Test
public void test_pow() {
    int result = lessSimpleCalculator.power(3, 2);
    assertEquals(9, result);
}

顺便说一句,查看您的 pom.xml,您正在混合 JUnit Jupiter 和旧的 JUnit 4。您可能应该与其中之一对齐:

<dependencies>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.11.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>5.13.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.13.0</version>
    <scope>test</scope>
  </dependency>
</dependencies>

当然,按照我的建议,你无论如何都不需要 Mockito,但我假设你还有其他测试仍然需要它。

© www.soinside.com 2019 - 2024. All rights reserved.