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&lt;String&gt; 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 日志记录。

部分内容参考自:http://www.jointforce.com/jfperiodical/article/1455