【问题标题】:How can I use mockito to Mock a class method that is inside another class如何使用 mockito 模拟另一个类中的类方法
【发布时间】:2025-12-05 01:20:10
【问题描述】:

我正在尝试使用 JUnit 和 Mockito 来模拟端到端方法(addSomething 方法)。很明显,在该方法中我使用了其他方法。 我的疑问是:

  • 要模拟端到端方法,我还需要模拟其他方法,对吧?
  • 如何模拟 addSomething 方法中的方法?

我想要的一个简单例子是:

方法A

public int summing(int sum){
 int A = 5;
 int B = 23;

 sum = SumOfIntegers(A,B);
 return sum;
}

方法B

private int SumOfIntegers(int number1, int number2){

try{
    result = number1 + number2;
 }catch (Exception e) {
        e.printStackTrace();
 }
return result;
}

我如何模拟类的方法 A,因为它正在调用私有方法?

【问题讨论】:

  • @Michael 谢谢,谢谢。
  • 你能告诉我们你到底想做什么(使用发布的代码作为支持,即不要说“方法”,而是说“方法 XXX”)。谢谢
  • @RC。我已经编辑了这个问题,但基本上我的问题的主要目标是:模拟 addSomething 类值得吗?如果是,我该怎么做?
  • "要模拟端到端方法,我也需要模拟其他方法,对吧?"没有。如果你模拟addSomethingaddSomething 的实现细节将无关紧要。您可以让addSomething 返回“假”响应(即任何适当的字符串)。

标签: java unit-testing methods junit mockito


【解决方案1】:

单元测试验证单元的公共可观察行为,即返回值以及与其依赖项的通信


您的问题是ServerProxy 存在隐藏的依赖关系。 你不应该在那个方法中实例化它,根本不应该在那个类中......

如果您严格遵循关注点分离/单一职责模式,依赖项的实例化是它自己的责任,不应由使用依赖项的对象完成。

总之,您应该通过依赖注入ServerProxy 对象注入到您的测试单元中,最好作为构造函数参数,最有可能使用DI框架。在这种情况下,将 ServerProxy 替换为可以为测试配置的模拟是微不足道的。

【讨论】:

    【解决方案2】:

    您需要模拟addSomething() 所属的类。

    假设您有一个使用该方法的类。

    public class ClassB {
      public String methodB(String jsonSomething) {
         ...
         String result = addSomething("{}");
        ...
      }  
    }
    
    public class ClassA {
      public String addSomething(String jsonSomething) {
         ...
      }  
    }
    

    在 ClassB 的测试类中,您将模拟 classA 对象,并为 addSomething 方法指定行为。您无需为 addSomething 中的内容指定任何模拟行为。

    @RunWith(MockitoJRunner.class)
    public class ClassBTest {
      @Mock
      private ClassA classA;
    
      @Test
      testMethodB() {
        given(classA.addSomething(anyString())).willReturn("{}"); // Here you are specifying the mocked behavior for addSomething
        ...
      }
    }
    

    【讨论】:

    • 嗨@alayor。感谢您的回答,但我认为您理解不好。我没有像你在这里提供的代码那样的 2 个类,我有一个类,里面有方法。我正在尝试模拟该类并测试该方法,唯一的问题是该方法内部还有其他方法,而我只是找不到解决方法。我是单元测试的新手,对此我感到很疯狂。
    • 立即查看帖子。我更新了我想要的更清晰的示例
    • 你不应该模拟你正在测试的课程。您可以做的是将您的私有方法放在另一个类中,然后模拟该类。
    • 我为什么不应该模拟我正在测试的课程?
    【解决方案3】:

    如果您打算模拟其范围是被测方法本地的对象的方法,那么这可能使用 PowerMock 之类的东西,但实际上这通常表明您的代码编写得不好以便于测试.

    我建议重构您的代码,以确保使用依赖注入将具有您想要模拟的方法的任何对象包含在类级别。使用 mockito 模拟这个非常简单,只需在测试中使用 @Mock 注释标记这些对象,并使用 @InjectMocks 标记正在测试的类。然后,这将确保在您的测试中将对象的模拟注入到被测类中,而不是对象的真实实例中,然后您可以存根您喜欢的所有方法。

    【讨论】:

      【解决方案4】:

      您不模拟方法,而是模拟整个类,并在调用它们的方法时让它们以您需要的方式响应。 那么如果你在一个类中使用方法A,而这个方法A使用方法B,你只mock方法A。类中的代码没有练习,所以你不需要mock整个链。这就是嘲讽的重点。你问的是这个吗?

      所以你永远不会模拟你在 Main 方法中使用的方法。

      【讨论】:

      • 感谢您的帮助。我现在明白你所说的了,但是我仍然无法通过模拟方法A来让我的单元测试通过我不知道为什么。
      最近更新 更多