SpringMVC + JUnit4 单元测试
依赖
只展示单元测试相关的部分
ssm/pom.xml
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.3.9.RELEASE</spring.version>
...
</properties>
<dependencies>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
...
</dependencies>
普通测试
/ssm/src/test/java/com/jerry/ssm/mapper/PoemMapperTest.java
package com.jerry.ssm.mapper;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.jerry.ssm.entity.Poem;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class PoemMapperTest{
@Resource
private PoemMapper poemMapper;
@Test
public void selectListTest() {
List<Poem> poemList = poemMapper.selectList(null);
for (Poem poem : poemList) {
System.out.println(poem);
}
}
}
Controller 测试
创建 Controller 测试基类
为了与Dao
、Service
分开所以 Controller
层单写一个基类,跟当前阶段无关的能不加载就省一下。
@RunWith(SpringJUnit4ClassRunner.class)
:照规矩写上即可。@WebAppConfiguration
:加载web上下文WebApplicationContext
,测controller层必须地。。。@ContextConfiguration(locations = { "classpath:application-spring.xml","classpath:application-web.xml" })
:
3.1.spring配置、spring-mvc配置
都要加载。
3.2. 正常我们都在spring配置
排除了对Controller
的扫描,交给spring-mvc配置
来管了对吧。
3.3. 为了将开发环境
和测试环境
分开,所有用到的配置文件都在src/test/resources/
单独创建了一份。跑单元测试时会优先来这里,这里没有才去src/java/resources/
找。
/ssm/src/test/java/com/jerry/ControllerBaseTest.java
package com.jerry;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
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.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/**
* 单元测试基类
*
* @author jerryjin
* @date 2019-06-02 17:02:30
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value = "src/main/webapp")
@ContextConfiguration(locations={"classpath:applicationContext.xml","classpath:spring-mvc.xml"})
@ComponentScan(basePackages={"com.jerry.ssm.controller", "com.jerry.ssm.service"})
// 如果不想测试产生的数据保存下来。可以开启事务默认回滚
//@Transactional
//@TransactionConfiguration( transactionManager = "transactionManager", defaultRollback = true)
public class ControllerBaseTest {
@Autowired
private WebApplicationContext webApplicationContext;
protected MockMvc mockMvc;
protected MockHttpServletRequest request;
protected MockHttpServletResponse response;
/**
* 初始化SpringmvcController类测试环境
*/
@Before
public void setup(){
//加载web容器上下文
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
创建 Controller 单元测试类
Eclipse
- 选中
PoemController.java
- 点击热键
Ctrl + N
- 注意:
1、就测试文件放置的位置。
2、是让此单元测试继承:测试基类ControllerBaseTest
- 选择要测试的方法
IDEA
在要被测试的 xxxController.java
文件中:
- 右键
Generate
或直接热键:Alt + Insert
- 选择
Test...
- 创建测试类
- 选择Junit 版本
- 测试类名称(通常就是原类加上
Test
结尾) - 测试类的父类:一般我们把一些基础配置写在父类,然后测试类直接继承即可。
- 测试类包名:与原类保持一致即可。
- 测试前后要执行的一些操作,能在父类统一写好的尽量在父类写。
- 选择要创建单元测试的方法。
/ssm/src/test/java/com/jerry/ssm/controller/PoemControllerTest.java
package com.jerry.ssm.controller;
import java.io.UnsupportedEncodingException;
import org.junit.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import com.jerry.ControllerBaseTest;
public class PoemControllerTest extends ControllerBaseTest {
@Test
public void testGetPome() throws UnsupportedEncodingException, Exception {
ResultActions resultActions = mockMvc.perform(
MockMvcRequestBuilders
.get("/pome")// 数据的格式请求的url,请求的方法是 get
.contentType(MediaType.APPLICATION_FORM_URLENCODED)// 数据的格式
.param("id","1")// 添加参数
);
MvcResult mvcResult = resultActions
// .andDo(MockMvcResultHandlers.print())// 打印出请求和相应的内容。如跳转视图的name以及传给视图的数据
// .andExpect(MockMvcResultMatchers.status().isOk()) //判断返回状态是否200
.andReturn();
String result = mvcResult.getResponse().getContentAsString();
System.out.println(result);
}
}
输出结果
{
"data":{
"id":1,
"title":"痴情癫",
"content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p",
"author":"笑虾"
}
}
导入静态方法
网上很多代码没有看到MockMvcRequestBuilders
直接就使用get()、post()、status(), print()
,又偏不开告诉你引用的哪个类。
mark下位置,没有的就在附近找找看不会太远。
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
总结
因为JUnit
创建项目时都带了,所以基本就是添加spring-test
依赖,然后创建单元测试并加上注解就行了。
对于controller
单元测试,感觉还是满麻烦的,如果要用,最好还是把模拟请求的方法都封装一下。