对于我的一个用例,我必须模拟一个自动连接的依赖,只有一个测试用例,而我希望其他测试使用原始的。
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
}
}
我想在一些特定的测试中模拟私有类变量'b'。我知道如果我必须在整个类中模拟B,我可以使用@Mock, @InjectMocks和MockitoAnnotations.initMocks(),但这将模拟' B '为其他测试用例以及我想要的原始行为。
您可以简单地创建一个模拟对象,并将其临时分配给变量b
。就像
public void test1() {
//normal test
}
而在另一个:
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;
}
}
请注意finally
条款。它的存在是为了确保在测试期间恢复类状态(自动连接依赖)。这是一个非常重要的做法,否则你的测试失败理论上会影响到你在同一类中的其他测试,这是你应该始终避免的。
通常,您不使用Spring进行单元测试,而是依赖于mock依赖项并将它们手动注入到测试对象中。因此,一个简单的测试方法可以像这样:
@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)));
}
如果你想注入一个真实的对象到a而不是模拟对象(无论什么原因)只需切换mockedB在Whitebox.setInternalState(...)
与你的真实对象。