之前是否模拟了一个模拟

之前是否模拟了一个模拟

本文介绍了在 Spring Context 加载实际的 Spring Bean 之前是否模拟了一个模拟 bean (@MockBean)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们以以下为例.

@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)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:45