设计Service层与WEB层单元测试
架构体系:分布式微服务(注:仅可参考逻辑,不可复制粘贴运行)
问题点 | 解决方法 |
---|---|
MockMVC控制台响应乱码 | 参考此文 |
配置等省略不可完全照搬 | 重在参考逻辑 |
参考链接1 | MockMvc详解 |
参考链接2 | 原生讲解 |
参考链接3 | SpringBoot+MockMVC |
目录结构:
web层测试MockMVC的过程及方法或API:
bean层代码块:
package com.asiainfo.aim.beans.common.second;
import com.cmos.common.bean.GenericBean;
import java.util.Date;
/**
* @Title:Role
* @Description:角色实体
* @author: wangsai
* @date 2019/8/13 11:57
*/
public class Role extends GenericBean {
/*GenericBean此类为公司封装:主要实现了序列化
public abstract class GenericBean implements JsonObjectBean, Serializable*/
/*
//当在赋值的时候固定有几种类型时,可以使用全局的静态常量来规范代码和使用
public static final String ROLE_DELETE = "0";
public static final String ROLE_USE = "1";
public static final String ROLE_NOUSE = "2";
//在实现序列化的类中加入,为了反序列化的时候确保类的兼容性,实质就是版本兼容控制
private static final long serialVersionUID = -7201270811147265166L;
*/
private String roleId; //角色编码
private String roleName; //角色名称
private String roleDesc; //角色描述
private Date createTime; //创建时间
private String roleStatus;//角色状态,0为删除,1为正常,2为已禁用
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getRoleStatus() {
return roleStatus;
}
public void setRoleStatus(String roleStatus) {
this.roleStatus = roleStatus;
}
@Override
public String toString() {
return "Role{" +
"roleId='" + roleId + '\'' +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
", createTime=" + createTime +
", roleStatus='" + roleStatus + '\'' +
'}';
}
}
dao层代码块:
package com.asiainfo.aim.dao.second;
import com.asiainfo.aim.beans.common.second.Role;
import java.util.List;
/**
* @Title:RoleDao
* @Description:角色管理模块接口
* @author: wangsai
* @date 2019/8/13 13:16
*/
public interface RoleDao {
/**
* 添加角色信息
* @param role
*/
void saveRoleInfo(Role role);
/**
* 删除角色信息
* @param roleId 唯一主键角色编码
*/
void deleteRoleInfo(String roleId);
/**
* 更新角色信息
* @param role
*/
void updateRoleInfo(Role role);
/**
* 单个查询角色信息
* @param roleId 唯一主键角色编码
* @return Role
*/
Role getRoleInfo(String roleId);
/**
* 全量查询角色信息
* @return List 包含所有角色信息
*/
List<Role> listRoleInfo();
}
iservice层代码块:
package com.asiainfo.aim.iservice.second;
import com.asiainfo.aim.beans.common.second.Role;
import java.util.List;
/**
* @Title:IRoleSV
* @Description:角色管理模块向外暴露的服务接口
* @author: wangsai
* @date 2019/8/13 13:20
*/
public interface IRoleSV {
/**
* 添加角色信息
* @param role
*/
void saveRoleInfo(Role role);
/**
* 删除角色信息
* @param roleId 唯一主键角色编码
*/
void deleRoleInfo(String roleId);
/**
* 更新角色信息
* @param role
*/
void updateRoleInfo(Role role);
/**
* 单个查询角色信息
* @param roleId 唯一主键角色编码
* @return Role
*/
Role getRoleInfo(String roleId);
/**
* 全量查询角色信息
* @return List 包含所有角色信息
*/
List<Role> listRoleInfo();
}
serviceImpl层代码块:
package com.asiainfo.aim.service.impl.second;
import com.alibaba.dubbo.config.annotation.Service;
import com.asiainfo.aim.beans.common.second.Role;
import com.asiainfo.aim.dao.second.RoleDao;
import com.asiainfo.aim.iservice.second.IRoleSV;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* @Title:
* @Description:角色管理模块服务接口的实现类
* @author: wangsai
* @date 2019/8/13 13:24
*/
@Service(group = "role")
public class RoleSVImpl implements IRoleSV {
//注入DAO层相关方法
@Autowired
private RoleDao roleDao;
/**
* 实现添加角色信息服务接口
* @param role
*/
@Override
public void saveRoleInfo(Role role) {
this.roleDao.saveRoleInfo(role);
}
/**
* 实现删除角色信息服务接口
* @param roleId 唯一主键角色编码
*/
@Override
public void deleRoleInfo(String roleId) {
this.roleDao.deleteRoleInfo(roleId);
}
/**
* 实现更新角色信息服务接口
* @param role
*/
@Override
public void updateRoleInfo(Role role) {
this.roleDao.updateRoleInfo(role);
}
/**
* 实现全量查询角色信息服务接口
* @param roleId 唯一主键角色编码
* @return list 包含所有的角色信息
*/
@Override
public Role getRoleInfo(String roleId) {
return this.roleDao.getRoleInfo(roleId);
}
@Override
public List<Role> listRoleInfo() {
return this.roleDao.listRoleInfo();
}
}
web层代码块:
package com.asiainfo.aim.web.controller.second;
import com.alibaba.dubbo.config.annotation.Reference;
import com.asiainfo.aim.beans.common.second.Role;
import com.asiainfo.aim.iservice.second.IRoleSV;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Title:
* @Description:
* @author: wangsai
* @date 2019/8/13 16:03
*/
@RestController
@RequestMapping("/role")
public class RoleController {
//调用服务层暴露的接口方法
@Reference(group = "role")
private IRoleSV roleSVImpl;
/**
* 添加角色信息
* @param role
*/
@GetMapping("/saveRoleInfo")
public void saveRoleInfo(Role role){
this.roleSVImpl.saveRoleInfo(role);
}
/**
* 删除角色信息
* @param roleId 唯一主键 角色编码
*/
@GetMapping("/deleteRoleInfo")
public void deleteRoleInfo(String roleId){
this.roleSVImpl.deleRoleInfo(roleId);
}
/**
* 更新角色信息
* @param role
*/
@GetMapping("/updateRoleInfo")
public void updateRoleInfo(Role role){
this.roleSVImpl.updateRoleInfo(role);
}
/**
* 查询的单个角色信息
* @param roleId
* @return
*/
@GetMapping("/getRoleInfo")
public Role getRoleInfo(String roleId){
return this.roleSVImpl.getRoleInfo(roleId);
}
/**
* 全量查询所有角色信息
* @return
*/
@GetMapping("/listRoleInfo")
public List<Role> listRoleInfo(){
return this.roleSVImpl.listRoleInfo();
}
}
service层测试代码块(放在serviceImpl工程目录内):
package com.asiainfo.aim.service.impl.second;
import com.alibaba.dubbo.config.annotation.Reference;
import com.asiainfo.aim.beans.common.second.Role;
import com.asiainfo.aim.iservice.second.IRoleSV;
import com.cmos.common.test.UnitTestBase;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Title: RoleSVImplTest
* @Description: service层单元测试
* @author: wangsai
* @date 2019/8/13 19:24
*/
public class RoleSVImplTest extends UnitTestBase {
//注入接口服务
@Reference(group = "role")
private IRoleSV iRoleSV;
/**
* 测试角色添加功能
*/
@Test
public void saveRoleInfo(){
Role role = new Role();
role.setRoleId("2");
role.setRoleName("添加");
role.setRoleDesc("新录入功能");
role.setCreateTime(new Date());
role.setRoleStatus("1");
iRoleSV.saveRoleInfo(role);
System.err.println(role);
}
/**
* 测试角色删除功能
*/
@Test
public void deleteRoleInfo(){
iRoleSV.deleRoleInfo("2");
}
/**
* 测试角色更新功能
*/
@Test
public void updateRoleInfo(){
Role role = new Role();
role.setRoleId("1");
role.setRoleName("角色更新");
role.setRoleDesc("新录入功能");
/*role.setCreateTime(new Date());
role.setRoleStatus("1");*/
iRoleSV.updateRoleInfo(role);
System.err.println(role);
}
/**
* 角色单个信息查询测试
*/
@Test
public void getRoleInfo(){
Role role = new Role();
role = iRoleSV.getRoleInfo("1");
System.err.println(role);
}
@Test
public void listRoleInfo(){
List<Role> roleList = new ArrayList<Role>();
roleList =iRoleSV.listRoleInfo();
System.err.println(roleList);
}
}
service层测试继承的代码块UnitTestBase为公司封装:
import com.cmos.common.test.UnitTestBase;
(public class UnitTestBase extends TestCase implements ApplicationContextAware )
web层测试代码块:
package com.asiainfo.aim.web.controller.second;
import com.asiainfo.aim.web.BaseUnitTest;
import org.junit.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import java.util.Date;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @Title: RoleControllerTest
* @Description: web层单元测试
* @author: wangsai
* @date 2019/8/13 19:13
*/
public class RoleControllerTest extends BaseUnitTest {
/**
* 测试角色添加功能
* @throws Exception
*/
@Test
public void saveRoleInfo() throws Exception{
mockMvc.perform(
MockMvcRequestBuilders
.get("/role/saveRoleInfo")//访问路径
//传参
.param("roleId", "2")
.param("roleName", "测试")
.param("roleDesc", "WEB层")
.param("createTime", String.valueOf(new Date()))
.param("roleStatus", "2")
)
.andDo(print())//打印响应头
.andExpect(status().isOk()).andReturn();//断言
}
/**
* 测试删除功能信息
* @throws Exception
*/
@Test
public void deleteRoleInfo() throws Exception{
mockMvc.perform(
MockMvcRequestBuilders
.get("/role/deleteRoleInfo")//访问路径
//传参
.param("roleId", "2")
)
.andDo(print())//打印响应头
.andExpect(status().isOk()).andReturn();//断言
}
/**
* 测试角色更新功能
* @throws Exception
*/
@Test
public void updateRoleInfo() throws Exception{
ResultActions resultActions = mockMvc.perform(
MockMvcRequestBuilders
.get("/role/updateRoleInfo")//访问路径
//传参
.param("roleId", "2")
.param("roleName", "更新测试成功")
.param("roleDesc", "WEB层")
);
resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8");//此处可让控制台的bean不会乱码
resultActions.andDo(MockMvcResultHandlers.print())//打印响应头
.andExpect(status().isOk()); //添加断言
}
/**
* 测试单个角色查询
* @throws Exception
*/
@Test
public void getRoleInfo() throws Exception{
mockMvc.perform(
MockMvcRequestBuilders
.get("/role/getRoleInfo")//访问路径
//传参
.param("roleId", "2")
)
.andDo(print())//打印响应头
.andExpect(status().isOk()).andReturn();//断言
}
/**
* 测试角色全量查询功能
* @throws Exception
*/
@Test
public void listRoleInfo() throws Exception{
ResultActions resultActions = mockMvc.perform(
MockMvcRequestBuilders
.get("/role/listRoleInfo").contentType (MediaType.APPLICATION_JSON_UTF8 )
);
resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8");//此处可让控制台的bean不会乱码
resultActions.andDo(MockMvcResultHandlers.print())//打印响应头
.andExpect(status().isOk()); //添加断言
}
}
web层测试继承的BaseUnitTest代码块:
package com.asiainfo.aim.web;
import com.asiainfo.aim.web.config.WebMockConfig;
import com.cmos.cache.service.ICacheService;
import com.cmos.common.dubbo.DubboRegistryInitializer;
import com.cmos.common.spring.DefaultApplicationContextInitializer;
import com.cmos.common.test.MockAppContextIntializer;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.MockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/**
* @author wangsai
* @date 2019/8/1
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(
classes = WebMockConfig.class,
initializers = {
DubboRegistryInitializer.class,
DefaultApplicationContextInitializer.class,
MockAppContextIntializer.class
})
public class BaseUnitTest {
@Autowired
protected WebApplicationContext context;
protected MockMvc mockMvc;
@Before
public void setupMockMvc() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
}