在日常开发过程中为了保证代码的正确通常我们要对自己写好的功能代码进行反复测试。比如说我们写好一个HTTP协议的接口。为了测试这个接口的正确性。我们很多时候会通过浏览器插件进行接口测试。这样操作既麻烦又费时。很多时候觉得这样麻烦只是简单的做下自测就将代码发布到测试环境交给测试人员进行测试。结果测试人员每次返回很多bug报告给开发人员。开发人员拿到bug报告通常也只会对具体bug进行针对性修改。修改完成同样只是做简单测试又提交给测试人员。测试人员再次测试有时可能会发现以前没有问题的地方,二次修改后会出现新的bug。从而导致一个问题可能会往往复复多次修改。采用单元测试工具进行代码测试就能够很好的解决这个问题。
采用单元测试的好处
1.一次编写多次运行。有可能你认为写好一个功能后为这个功能再写一个单元测试会很麻烦。但是你有没有想过写了这个单元测试后你就可以用它来测试你的代码直到你的代码没有问题。他能够有效减少你测试所花费的时间。
2.避免日常开发过程中某个功能迭代过程中影响另一个功能。因为每次开发一个功能时都为其开发一个单元测试。所以当你修改B功能时很有可能在修改的过程中影响到A功能的正确性。如果不写单元测试。这个问题就很难发现。只有进行功能回测才能发现。功能回测是很费时间的。也是很烦躁的事情。有了单元测试。每次打包都会进行单元测试。有问题能够将问题扼杀到摇篮之中。
如何编写单元测试
目前采用SpringBoot开发应用较多。所以本文也只针对SpringBoot的单元测试进行总结说明。先来个简单实例代码。首先给出单元测试依赖jar包。maven依赖
<!-- Spring事务包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- SpringBoot测试包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 模拟Http请求测试包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
<version>2.0.8</version>
<scope>test</scope>
</dependency>
单元测试类
package com.mic.service;
import java.util.HashMap;
import java.util.Map;
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.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//import org.springframework.test.context.transaction.TransactionConfiguration;
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.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import net.minidev.json.JSONObject;
//@TransactionConfiguration(transactionManager="transactionManager",defaultRollback=true) 过时
//@Transactional(transactionManager="transactionManager")
@Transactional
@Rollback(value=true)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = Application.class)
public class ApplicationTest {
@Test
public void contextLoads() {
}
private MockMvc mockMvc; // 模拟MVC对象,通过MockMvcBuilders.webAppContextSetup(this.wac).build()初始化。
@Autowired
private WebApplicationContext wac; // 注入WebApplicationContext
// @Autowired
// private MockHttpSession session;// 注入模拟的http session
//
// @Autowired
// private MockHttpServletRequest request;// 注入模拟的http request\
@Before // 在测试开始前初始化工作
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testQ1() throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/index")
.content(JSONObject.toJSONString(map)))
.andReturn();// 返回执行请求的结果
int status = result.getResponse().getStatus();
String content = result.getResponse().getContentAsString();
Assert.assertTrue("正确", status == 200);
Assert.assertFalse("错误", status != 200);
System.out.println("返回结果:"+status);
System.out.println(content);
System.out.println(result.getResponse().getContentAsString());
}
@Test
public void testQ2() throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/index")
.content(JSONObject.toJSONString(map)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
}