【问题标题】:How to mock classes with constructor injection如何使用构造函数注入模拟类
【发布时间】:2018-11-02 06:14:55
【问题描述】:

如何在Mockito中获取构造函数注入

我有以下课程:

class A {

  private B mB;

  A(B b) {
     mB = b;
  }

 void String someMethod() {
     mB.execute();
  }
}

如何使用模拟类 A 和使用类 B 测试 someMethod

B b = Mockito.mock(B.class)
Mockito.when(b.execute()).thenReturn("String")

A a = Mockito.mock(A.class)
//somehow inject b into A and make the below statement run
Mockito.when(a.someMethod()).check(equals("String"))
   

【问题讨论】:

  • 你不使用 Mockito。使用 Powermock。
  • 如何使用Powermock?
  • 大概找个教程吧。那里有很多。

标签: java android unit-testing testing mockito


【解决方案1】:

您需要创建真正的 A 类,因为您想对其进行测试,但您需要模拟 A 类中使用的其他类。另外,你可以找到 mockito documentation 说不要嘲笑一切。

class ATest {
        @Mock
        private B b;
        private A a;
        @Before
        public void init() {
            MockitoAnnotations.initMocks(this);
            a = new A(b);
        }
        @Test
        public String someMethodTest() {
            String result = "result";
            Mockito.when(b.execute()).thenReturn(result);
            String response = a.someMethod();
            Mockito.verify(b,  Mockito.atLeastOnce()).execute();
            assertEquals(response, result);
        }
    }

【讨论】:

    【解决方案2】:

    另一种将模拟注入真实对象(因为 A 应该是真实对象)的方法是使用注释,它们会创建您想要的对象:

    @Mock 
    B mockOfB;
    
    @InjectMocks
    A realObjectA;
    
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    

    然后,就像他们说的,在没有 mockito 的情况下运行你想要测试的方法(因为你想测试它,所以在真实实例上调用它)并根据你的期望检查结果。

    可以以任何方式模拟对象 B 的行为,以满足您的需求。

    【讨论】:

      【解决方案3】:

      您想测试A 类的someMethod()。测试B 类的execute() 应该在另一个测试中进行,因为B 的实例在您的情况下是一个依赖项。 execute() 的测试应该在不同的测试中进行。

      您不需要测试 B 对象的行为方式,因此您需要模拟它,然后检查是否调用了 execute()

      所以在您的情况下,您的测试将如下所示:

        B b = Mockito.mock(B.class);
        A a = new A( b );
        a.someMethod();
        Mockito.verify( b, Mockito.times( 1 ) ).execute();
      

      【讨论】:

        【解决方案4】:

        在我看来,您混淆了两种测试方式。

        如果您想使用 Mockito 编写测试,您只需创建某个类的模拟并使用它。这个模拟没有任何与真实对象相关的东西,因为您可以(应该)模拟测试中调用的每个方法。这就是为什么模拟 B 类没有任何意义 - 它根本不被 A 类使用。

        否则,如果你想测试A 类的真实行为,那你为什么要模拟它?使用类B 的模拟实例创建类A 的真实实例。

        就是这样!不要混淆。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-19
          • 1970-01-01
          • 2017-01-29
          • 1970-01-01
          • 1970-01-01
          • 2015-08-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多