问题描述
让我们以以下为例.
@Autowired
@MockBean
private Foo foobar;
Spring Context 是否先加载类 Foo
,然后再应用模拟?或者 @Mockbean
是否以某种方式被检测到,Spring 创建并应用模拟而不是将 Foo
类加载到 Spring 上下文中.我怀疑是后者,但我想确认一下.
Does the Spring Context load the class Foo
first, and then apply the mock? Or does the @Mockbean
get detected somehow, and Spring creates and applies the mock instead of loading the class Foo
into the Spring Context. I have a suspicion that it is the latter, but I would like confirmation.
推荐答案
Spring 会抛出异常.
Spring will throw an exception.
让我们定义 Foo 类.
Let's define the class Foo.
@Component
public class Foo {
public Foo() {
System.out.println("I am not a mock");
}
}
每当使用 @Autowired
进行测试时,spring 都会注入一个 Foo 实例,构造函数将打印 "I am not a mock"
,如下面的代码所示.
Whenever testing using @Autowired
, spring injects an instance of Foo and the constructor will print "I am not a mock"
, as in the code below.
@SpringBootTest(classes = Main.class)
@RunWith(SpringRunner.class)
public class FooTest {
@Autowired
Foo foo;
@Test
public void test() {
System.out.println(foo);
}
}
另一方面,使用@MockBean,spring 不会创建真正的bean,并且不会打印构造函数中的消息.此场景由以下代码表示.
On the other hand, using @MockBean, spring will not create the real bean and the message in the constructor will not be printed. This scenario is represented by the following code.
@SpringBootTest(classes = Main.class)
@RunWith(SpringRunner.class)
public class FooTest {
@MockBean
Foo foo;
@Test
public void test() {
System.out.println(foo);
}
}
然而,当你尝试同时使用这两个注解时,spring 会抛出一个由 IllegalStateException
引起的 BeanCreationException
.这意味着字段 foo 不能具有现有值.执行以下代码时会发生这种情况:
However, when you try to use both annotations together, spring will throw a BeanCreationException
caused by an IllegalStateException
. It means that the field foo cannot have an existing value. This scenario will happen in executing the code below:
@SpringBootTest(classes = Main.class)
@RunWith(SpringRunner.class)
public class FooTest {
// this will not work
@Autowired
@MockBean
Foo foo;
@Test
public void test() {
System.out.println(foo);
}
}
堆栈跟踪将类似于:
org.springframework.beans.factory.BeanCreationException: Could not inject field: com.tbp.Foo com.FooTest.foo; nested exception is java.lang.IllegalStateException: The field com.tbp.Foo com.FooTest.foo cannot have an existing value
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.inject(MockitoPostProcessor.java:413) ~[spring-boot-test-1.5.2.RELEASE.jar:1.5.2.RELEASE]
这篇关于在 Spring Context 加载实际的 Spring Bean 之前是否模拟了一个模拟 bean (@MockBean)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!