一、Spring Boot 对测试的支持
- Spring Boot 的测试与 Spring MVC 很类似。
- Spring Boot 提供了 spring-boot-starter-test 依赖用于进行测试相关的支持,并且每次新建 Spring Boot 项目都会默认添加,同时会在 src/test/java 目录下新建一个 项目名+Test 的测试类。
- 接下来用一个简单的 Spring Boot 进行测试。
1、新建项目
- 新建一个 Spring Boot 项目,依赖选择为 JPA、Web 和 hsqldb。
- 其中 hsqldb 为内存数据库。
- 项目的 POM 文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.0.M4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.pyc</groupId> <artifactId>springtest</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springtest</name> <packaging>jar</packaging> <description>A project of spring test</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
- application.properties 文件不用编辑。
2、待测试的业务代码
- 编辑一个业务用于测试。
2.1、实体类
- 首先是实体类,代码如下:
package com.pyc.springtest.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Person { @Id @GeneratedValue private Long id; private String name; public Person() { super(); } public Person(String name) { super(); this.name = name; } public void setId(Long id) { this.id = id; } public Long getId() { return id; } public void setName(String name) { this.name = name; } public String getName() { return name; } }
2.2、实体类 Repository
- 新建一个 PersonRepository,代码如下:
package com.pyc.springtest.dao; import com.pyc.springtest.domain.Person; import org.springframework.data.jpa.repository.JpaRepository; public interface PersonRepository extends JpaRepository<Person, Long> { }
- 因为是用于测试,因此便不再添加额外的方法,继承默认的方法即可。
2.3、控制器
- MVC 种控制器是必不可少的,控制器代码如下:
package com.pyc.springtest.web; import com.pyc.springtest.dao.PersonRepository; import com.pyc.springtest.domain.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/person") public class PersonController { @Autowired PersonRepository personRepository; @RequestMapping(method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE}) public List<Person>findAll(){ return personRepository.findAll(); } }
3、测试用例
- 打开项目默认创建的测试类,修改并编辑代码如下:
package com.pyc.springtest; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.pyc.springtest.dao.PersonRepository; import com.pyc.springtest.domain.Person; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SpringtestApplication.class) @WebAppConfiguration @Transactional class SpringtestApplicationTests { @Autowired PersonRepository personRepository; MockMvc mvc; @Autowired WebApplicationContext webApplicationContext; String expectedJson; protected String Obj2Json(Object obj) throws JsonProcessingException{ ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(obj); } @Before public void setUp() throws JsonProcessingException{ Person p1 = new Person("pyc"); Person p2 = new Person("ycy"); personRepository.save(p1); personRepository.save(p2); expectedJson = Obj2Json(personRepository.findAll()); mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test public void testPersonController() throws Exception{ String uri = "/person"; MvcResult result = mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON)) .andReturn(); int status = result.getResponse().getStatus(); String content = result.getResponse().getContentAsString(); Assert.assertEquals("错误,正确的返回值为 200", 200, status); Assert.assertEquals("错误,返回值和预期返回值不一致", expectedJson, content); } }
- 对几个注解说明一下:
@SpringApplicationConfiguration
替代@ContextConfiguration
来配置 Spring Boot 的 Application Context。@Transactional
注解可保证每次测试后的数据将会被回滚。@Befor
注解是 Junit 提供的,可用于在测试开始前进行一些初始化的工作。
4、执行测试
- 在项目根路径打开 Terminal,像我一样使用 IDEA 的直接可在编辑窗口下面的 Terminal 窗口直接打开。
- 在 Terminal 窗口输入
mvn clean package -Dmaven.test.skip=true
命令回车,等待程序的自动执行,再无错误的情况下,Terminal 窗口的结果界面如下:
- 并且在 Project 窗口的 target 目录下会生成一个项目的 JAR 包,如下: