IT技术篇中北软院创新实验室SpringBoot极简教程 · Spring Boot

SpringBoot 1.4 之后测试代码该如何写

2017-11-06  本文已影响710人  HikariCP

前言

测试在 SpringBoot 1.4 版本之后进行了改进,Testing improvements in Spring Boot 1.4。由于 Spring Boot 1.4 之前的测试方式均属于集成测试。一个单纯的单元测试不应该创建和加载 Spring 的上下文。在 1.4 版本之前想要使用单元测试测试一个带有@Autowired注解的外部 services 的 controller 而不用去加载Spring上下文,是不可能的。


简介

Spring Boot 1.4 解决的另外一个问题是,可以测试一段代码。不用启动服务器。并且不用启动整个Spring上下文,Spring Boot 1.4 通过新的Test Slicing的特性 就可以完成,这个特性被设计成可以至启动一小片的Spring上下文。这时的测试单个的代码片段更加容易了。你可以这样去测试你的应用中的特定代码片段

解决的问题;大型的应用要测试的话,如果它启动Spring上下文,会很耗费时间


SpringBoot 1.4-

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests {

}

Or

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class)
public class ApplicationTests {

}

SpringBoot 1.4+

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class)
public class ApplicationTests {

}

注解


实例

单例测试

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
@AutoConfigureWebMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;
    
    @Test
    public void index() throws Exception {
        this.mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
//                .andExpect(view().name("index"))
                .andExpect(content().string(Matchers.containsString("Hello World")))
                .andDo(print());
    }
}

集成测试

@RunWith(SpringRunner.class)
//@WebMvcTest(controllers = HelloController.class)
//@AutoConfigureWebMvc
public class HelloControllerTest extends C1ApplicationTests {

//    @Autowired
    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
    }

    @Test
    public void index() throws Exception {
        this.mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
//                .andExpect(view().name("index"))
                .andExpect(content().string(Matchers.containsString("Hello World")))
                .andDo(print());
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = C1Application.class)
public class C1ApplicationTests {
    
}

方法解析:


控制台

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /hello
       Parameters = {}
          Headers = {}

Handler:
             Type = nuc.jyg.c1.web.HelloController
           Method = public java.lang.String nuc.jyg.c1.web.HelloController.index()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8], Content-Length=[11]}
     Content type = application/json;charset=UTF-8
             Body = Hello World
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

扩展

事物回滚

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional

上面两句的作用是,让我们对数据库的操作会事务回滚,如对数据库的添加操作,在方法结束之后,会撤销我们对数据库的操作。

为什么要事务回滚?

这里需要注意,如果使用了事物回滚。那么有些时候对数据库内容进行修改操作后你将不能直观的看到变化。如何判断是否成功了,可以在返回的数据中带上data字段,将修改的数据存进去传向前台。

使用andExpect方法对返回的数据进行判断,用“$.属性”获取里面的数据,如要获取返回数据中的"data.name",可以写成"$.data.name"。下面的例子是判断返回的 data.name = “测试”。

MockHttpServletRequestBuilder.andExpect(jsonPath("$.data.name", is("##")))) 

不同环境的测试

@ActiveProfiles(profiles = "test") 在测试类上面指定profiles,可以改变当前spring 的profile,来达到多环境的测试

上一篇下一篇

猜你喜欢

热点阅读