- 新建一个测试配置类 TestApplication - @Configuration @EnableAutoConfiguration
 @ComponentScan(
 excludeFilters = @ComponentScan.Filter(value = {
 Application.class,
 ApplicationChecker.class
 }, type = FilterType.ASSIGNABLE_TYPE))
 public class TestApplication {
 // 配置测试使用内存数据库
 @Bean
 public DataSource dataSource() {
 return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
 }
 }
- 新建一个测试公共类 CommonBeanIntegrationTest - @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TestApplication.class)
 // 重新加载 Spring 上下文
 // @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
 public abstract class CommonBeanIntegrationTest {
 @After
 public void emptyDatabases() {
 // 清空数据库,运行速度相对于每次重新加载 Spring 上下文快很多
 }
 }
- 正式开始写测试 - 常规测试类结构
 - public class UserTest extends CommonBeanIntegrationTest { @Autowired
 private UserAccessor userAccessor; // 准备测试的 Bean
 @Autowired
 private UserRepository userRepository; // 测试中需要用到的辅助 Bean
 @Before
 public void setUp() {
 // 每个测试开始前的操作
 }
 @Test
 public void should_save_user_with_username() {
 // given
 String username = "foo";
 // when
 userAccessor.save(username);
 // then
 assertThat(userRepository.findOne(1).getUsername, is(username));
 }
 @After
 public void tearDown() {
 // 每个测试执行后的操作
 }
 }- 使用 Mock 时测试类结构
 - @RunWith(MockitoJUnitRunner.class) public class HttpClientTest {
 @Mock
 private ServerProperties serverProperties;
 @InjectMocks // 把 @Mock 注解的对象注入到 httpClient 中
 private HttpClient httpClient;
 @Test
 public void should_get_correct_port(){
 when(serverProperties.getPort()).thenReturn(8080);
 assertThat(httpClient.get(ApiUrl.list_node).getPort(), is(8080));
 }
 }- 混合使用前两种
 - public class UserTest extends CommonBeanIntegrationTest { @Autowired
 private UserRepository userRepository;
 @Mock
 private HttpClient httpClient;
 @Autowired
 @InjectMocks
 private UserAccessor userAccessor; // 准备测试的 Bean
 @Before
 public void setUp() {
 MockitoAnnotations.initMocks(this); // 初始化并注入 @Mock 注解的对象
 // 强制将 Mock 的 httpClient 对象注入 userAccessor 中
 // ReflectionTestUtils.setField(userAccessor, "httpClient", httpClient);
 }
 @Test
 public void test_something(){
 // Test Code
 }
 }- 同时在需要测试的 Bean 上使用 @Autowired 和 @InjectMocks 注解后,可以达到只 Mock 需要 Mock 的对象,而其它对象依然是注入的真实对象的效果。 
 但是有时候可能会出现我们 Mock 的对象还是注入的真实对象的情况,此时可以使用 Spring Boot 提供的 ReflectionTestUtils 在 @Before 中强制手动设置需要 Mock 的对象的值。
