Spring Boot 1.4 单元测试
在 1.3 中单元测试这样子的类似代码:
// SpringJUnit 支持,由此引入 Spring-Test 框架支持!
@RunWith(SpringJUnit4ClassRunner.class)
// 指定我们 SpringBoot 工程的 Application 启动类
@SpringApplicationConfiguration(classes = App.class)
// 由于是 Web 项目,Junit 需要模拟 ServletContext,因此我们需要给我们的测试类加上 @WebAppConfiguration。
@WebAppConfiguration
public class HelloServiceTest {
}
在 1.4 中 SpringApplicationConfiguration 标记为过时了,所以官方就不建议这么使用了,那么在 1.4 中单元测试怎么使用呢?类似代码如下:
一、建立一个整合了 mybatis 的工程
详见:http://www.cnblogs.com/lspz/p/6723603.html
二、编写测试类
测试类的文件结构,保持 src/test/Java 和 src/main/java 结构一直,即:包 + 文件夹。
如:com.example 包 service 中类的测试,那么在 src/test/java 也是建立 com.example 包,再在包下建立文件夹 service.
1、服务类的
package com.example.mapper;
import com.example.dto.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestUserMapper {
@Autowired
private UserMapper userMapper;
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testGetById</span><span class="hljs-params">()</span> {
<span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> userMapper.getById(<span class="hljs-number">1L</span>);
Assert.assertTrue(<span class="hljs-string">"数据集不对"</span>, user.getAge() == <span class="hljs-number">18</span>);
Assert.assertTrue(<span class="hljs-string">"数据一致"</span>, user.getName().equals(<span class="hljs-string">"张三"</span>));
}
}
2.controller 类的
package com.example.web;
import com.example.dto.User;
import com.example.mapper.UserMapper;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class TestExample {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> MockMvc mvc;
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserMapper userMapper;
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testGetById</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception {
<span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> userMapper.getById(<span class="hljs-number">1L</span>);
<span class="hljs-type">String</span> <span class="hljs-variable">uri</span> <span class="hljs-operator">=</span> <span class="hljs-string">"/getUser/1"</span>;
<span class="hljs-type">MvcResult</span> <span class="hljs-variable">mvcResult</span> <span class="hljs-operator">=</span> mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON))
.andReturn();
<span class="hljs-type">int</span> <span class="hljs-variable">status</span> <span class="hljs-operator">=</span> mvcResult.getResponse().getStatus();
<span class="hljs-type">String</span> <span class="hljs-variable">content</span> <span class="hljs-operator">=</span> mvcResult.getResponse().getContentAsString();
Assert.assertTrue(<span class="hljs-string">"错误,正确的返回值为200"</span>, status == <span class="hljs-number">200</span>);
Assert.assertFalse(<span class="hljs-string">"数据不一致"</span>, !user.toString().equals(content));
}
}
controller 类的第二种写法
package com.example.web;
import java.net.URL;
import com.example.dto.User;
import com.example.mapper.UserMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestExample2 {
@LocalServerPort
private int port;
<span class="hljs-keyword">private</span> URL base;
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> TestRestTemplate template;
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserMapper userMapper;
<span class="hljs-meta">@Before</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setUp</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception {
<span class="hljs-built_in">this</span>.base = <span class="hljs-keyword">new</span> <span class="hljs-title class_">URL</span>(<span class="hljs-string">"http://localhost:"</span> + port + <span class="hljs-string">"/getUser/1"</span>);
}
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getHello</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception {
<span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> userMapper.getById(<span class="hljs-number">1L</span>);
ResponseEntity<String> response = template.getForEntity(base.toString(),
String.class);
<span class="hljs-type">int</span> <span class="hljs-variable">status</span> <span class="hljs-operator">=</span> response.getStatusCodeValue();
<span class="hljs-type">String</span> <span class="hljs-variable">content</span> <span class="hljs-operator">=</span> response.getBody();
assertEquals(<span class="hljs-string">"错误,正确的返回值为200"</span>, status, <span class="hljs-number">200</span>);
assertThat(content, equalTo(user.toString()));
}
}
三、总结
(1)依赖包的引入:pom.xml 中仅依赖 spring-boot-starter-test,它把相关的依赖全部引入。
(2)@RunWith(SpringRunner.class) 告诉 JUnit 运行使用 Spring 的测试支持。SpringRunner 是 SpringJUnit4ClassRunner 的新名字,这个名字只是让名字看起来简单些。
(3)@SpringBootTest 的意思是“带有 Spring Boot 支持的引导程序”(例如,加载应用程序、属性,为我们提供 Spring Boot 的所有精华部分)。
(4)通过 webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT 我们可以让内置的服务器在随机端口启动。
(5)@LocalServerPort 注释注入实际的端口
(6)如果你需要测试 JSON 序列化是否如预期般运营,你可以使用 @JsonTest
- 自动配置 Jackson 和 / 或 Gson。
- 添加你可以定义的任一模块或者 @JsonComonent beans。
- 触发任何 JacksonTester 或 GsonTester 字段的初始化。
(7)测试您应用程序的 JPA 插件 (Hibernate +Spring 数据) 可以使用 @DataJpaTest 注释。@DataJpaTest 将会这样:
- 配置一个内存数据库。
- 自动配置 Hibernate,Spring 数据和数据源。
- 执行 @EntityScan。
- 打开 SQL 日志记录。