> For the complete documentation index, see [llms.txt](https://jack80342.gitbook.io/spring-boot/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jack80342.gitbook.io/spring-boot/iv.-spring-boot-features/43.-testing/43.3-testing-spring-boot-applications/43.3.5-mocking-and-spying-beans.md).

# 43.3.5 模拟和监视bean

有时候需要在运行测试用例时mock一些组件，例如，你可能需要一些远程服务的门面，但在开发期间不可用。Mocking在模拟真实环境很难复现的失败情况时非常有用。

Spring Boot提供一个`@MockBean`注解，可用于为`ApplicationContext`中的bean定义一个Mockito mock，你可以使用该注解添加新beans，或替换已存在的bean定义。该注解可直接用于测试类，也可用于测试类的字段，或用于`@Configuration`注解的类和字段。当用于字段时，创建mock的实例也会被注入。Mock bean每次调用完测试方法后会自动重置。

**注** 如果你的测试使用了Spring Boot的测试注解（比如`@SpringBootTest`），这个特性会被自动启用。要换一种方式使用这个特性的话，需要明确地添加一个监听器。如下所示：

```java
@TestExecutionListeners(MockitoTestExecutionListener.class)
```

下面的示例使用mock实现替换存在的`RemoteService` bean：

```java
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;
import org.springframework.test.context.junit4.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {

    @MockBean
    private RemoteService remoteService;

    @Autowired
    private Reverser reverser;

    @Test
    public void exampleTest() {
        // RemoteService has been injected into the reverser bean
        given(this.remoteService.someCall()).willReturn("mock");
        String reverse = reverser.reverseSomeCall();
        assertThat(reverse).isEqualTo("kcom");
    }

}
```

此外，你可以使用`@SpyBean`，来用Mockito`spy`包装任何已存在的bean。具体参考[Javadoc](https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/api/org/springframework/boot/test/mock/mockito/SpyBean.html)。

**注** Spring的测试框架会缓存测试之间应用上下文，并为共享相同配置的测试重用上下文。使用`@MockBean`或者`@SpyBean`会影响缓存键，很可能会增加上下文的数量。
