JUnit Mockito:测试静态方法并在内部调用另一个存根静态方法不起作用

发布于 2025-01-11 13:22:51 字数 580 浏览 0 评论 0原文

class A {
   public static int f1() {
      return 1;
   }
   
   public static int f2() {
      return A.f1();
   }
}

class ATest {
   @Test
   void testF2() {
      try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
         aStatic.when(A::f1).thenReturn(2);
         int ret = A.f2(); // getting 0 here
         assertEquals(ret, 2);
      } catch(Exception e) {
      
      }
   }
}

在 testF2 中我想测试静态函数 A::f2()。

它内部调用另一个静态函数A::f1()。

我做了存根 A::f1() 使用“MockedStatic”和“when”方式返回 2。

但它不起作用,它返回0。

如何解决它?

class A {
   public static int f1() {
      return 1;
   }
   
   public static int f2() {
      return A.f1();
   }
}

class ATest {
   @Test
   void testF2() {
      try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
         aStatic.when(A::f1).thenReturn(2);
         int ret = A.f2(); // getting 0 here
         assertEquals(ret, 2);
      } catch(Exception e) {
      
      }
   }
}

In the testF2 I want to test static function A::f2().

And it internally calls another static function A::f1().

I did stub A::f1() to return 2 using "MockedStatic" and "when" way.

But it's not working, it's returning 0.

How to solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一场春暖 2025-01-18 13:22:51

当您使用静态方法模拟类时,所有静态方法都会被模拟。如果您只想模拟 1 个方法的行为,则必须将 Mockito.CALLS_REAL_METHODS 参数添加到 Mockito.mockStatic() 中,如以下示例所示。

 @Test
  void testF2() {
    try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class, Mockito.CALLS_REAL_METHODS)) {
      aStatic.when(A::f1).thenReturn(2);
      int ret = A.f2(); // getting 2 here
      Assert.assertEquals(2, ret); // (expected, result)
    } catch(Exception e) {

    }
  }

这样,只有 f1 方法调用被模拟,但 f2 调用调用真实代码。

When you mock a class with static methods, all static methods are mocked. If you only want to mock the behavior of only 1 method, you have to add Mockito.CALLS_REAL_METHODS argument to Mockito.mockStatic() as you can see in the following example.

 @Test
  void testF2() {
    try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class, Mockito.CALLS_REAL_METHODS)) {
      aStatic.when(A::f1).thenReturn(2);
      int ret = A.f2(); // getting 2 here
      Assert.assertEquals(2, ret); // (expected, result)
    } catch(Exception e) {

    }
  }

This way only the f1 method invocation is mocked but f2 invocation calls the real code.

此生挚爱伱 2025-01-18 13:22:51

我认为您错过了指定模拟行为:

class ATest {
  @Test
  void testF2() {
    try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
        aStatic.when(A::f1).thenReturn(2);
        aStatic.when(A::f2).thenReturn(A.f1()); // <- added this
        int ret = A.f2(); // getting 0 here
        Assertions.assertEquals(ret, 2);
    } catch (Exception e) {

    }
  }
}

通过告诉模拟在调用 A.f2() 时做什么,测试运行良好。

更新:
模拟会做你告诉他们的事情,如果你不告诉调用方法时要做什么,他们什么也不做,这就是为什么你也必须模拟 f2

您想测试 A,然后模拟它不是您的朋友。我通常使用 Mockito.spy() 来部分模拟我的测试对象。您想模拟 f1 但测试 f2,我不想不要认为 spy 在这里适用,因为没有实例可以监视。

我建议您重新排列 A 避免静态方法(如果可能)或使用可以模拟的参数。

I think you miss to specify a mock behavior:

class ATest {
  @Test
  void testF2() {
    try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
        aStatic.when(A::f1).thenReturn(2);
        aStatic.when(A::f2).thenReturn(A.f1()); // <- added this
        int ret = A.f2(); // getting 0 here
        Assertions.assertEquals(ret, 2);
    } catch (Exception e) {

    }
  }
}

by telling the mock what to do when A.f2() is invoked, test runs fine.

Update:
Mocks do what you tell them, if you don't tell what to do when a method is invoked they do nothing, that's why you have to mock f2 too.

You want to test A, then mock it is not your friend. I normally use a Mockito.spy() to partially mock my subject under test .You want to mock f1 but test f2, I don't think spy applies here because there is no instance to spy..

I suggest you to rearrange A avoiding static methods if possible or using parameters you can mock.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文