如何使用构造函数注入来模拟类

时间:2018-05-23 09:57:40

标签: java android unit-testing testing mockito

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

我有以下课程:

class A{

  private B mB;

  A(B b){
     mB = b;
  }

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

如何使用模拟课someMethod和课程A使用

测试B
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"))

4 个答案:

答案 0 :(得分:3)

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

如果您想使用Mockito编写测试,只需创建一个类的模拟并使用它。这个模拟没有任何与真实对象相关的东西,因为你可以(应该)模拟测试中调用的每个方法。这就是为什么模拟类view.fit(source.getExtent(), { duration: 1000 }); 没有任何意义 - 它只是不被类B使用。

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

就是这样!不要混淆。

答案 1 :(得分:2)

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

@Mock 
B mockOfB;

@InjectMocks
A realObjectA;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

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

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

答案 2 :(得分:1)

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

您不需要测试B对象的行为方式,因此您需要对其进行模拟,然后检查是否已调用B

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

execute()

答案 3 :(得分: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);
        }
    }