简体   繁体   English

Mockito 与春天

[英]Mockito with Spring

For one of my use case, I have to mock an autowired dependency only a single test case, while I want other tests to use the original one.对于我的一个用例,我必须仅模拟一个自动装配的依赖项,而我希望其他测试使用原始测试用例。

public class A {

    @Autowired
    private B b;
}

Class TestA {

    @Autowired
    private A a;

    void test1() {
    //using B without mock.
    }

    void test2() {
    // mock B b in A here
    }
}

I want to mock the private class variable 'b' here in some particular tests.我想在一些特定的测试中模拟私有类变量“b”。 I know if I have to mock B in entire class I can use @Mock, @InjectMocks and MockitoAnnotations.initMocks(), but that will mock 'b' for the other test cases as well where I want original behavior.我知道如果我必须在整个班级中模拟 B,我可以使用 @Mock、@InjectMocks 和 MockitoAnnotations.initMocks(),但这将模拟其他测试用例的 'b' 以及我想要原始行为的地方。

You can simply create a mock object, and temporarily assign it to variable b .您可以简单地创建一个模拟对象,并将其临时分配给变量b Something like就像是

public void test1() {
   //normal test
}

while in the other:而在另一个:

public void test2() {
   try {
      B autowiredObject = b; //saving the original reference
      b = mock(B.class);
      when(b.someGetFunction()).thenReturn("it is mocked");
      //rest of your test
   } finally {
      b = autowiredObject;
   }
}

Please note the finally clause.请注意finally子句。 It is there to ensure that the class state (autowired dependency) gets restored during your test.它可以确保在测试期间恢复类状态(自动装配的依赖项)。 This is a very important practice, otherwise a fail in your test could theorertically affect your other tests in the same class, which is something you should always avoid.这是一个非常重要的实践,否则您的测试失败理论上可能会影响您在同一班级中的其他测试,这是您应该始终避免的。

Usually, you don't use Spring for unit-testing but rely on mocking dependencies and inject them manually into the test-object.通常,您不使用 Spring 进行单元测试,而是依靠模拟依赖项并将它们手动注入到测试对象中。 A simple test method therefore can look like this:因此,一个简单的测试方法可能如下所示:

@Test
public void testSomethingWithA() throws Exception {
    // Arrange
    A sut = new A();
    B mockedB = mock(B.class);

    // inject B into A
    Whitebox.setInternalState(sut, "b", mockedB);

    // Act
    Object retVal = sut.doSomething();

    // Assert
    assertThat(retVal, is(equalTo(someExpectedValue)));
}

If you want to inject a real object into A instead of a mocked object (for whatever reason) simply switch mockedB in Whitebox.setInternalState(...) with your real object.如果您想将真实对象注入 A 而不是模拟对象(无论出于何种原因),只需将Whitebox.setInternalState(...) mockedB 与您的真实对象切换即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM