依然接上一篇 学习Elasticsearch记录 的代码,整合了mockmvc来做自动化测试用例,学习过程以及感受记录于此
个人水平所限,肯定会有很多不足,请指正
项目路径:https://github.com/hallowold/elasticSearchDemo1
先上代码
首先,要在pom.xml中引入依赖,可能引多了,不过这些写上是没问题的
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-test</artifactId> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.testng</groupId> | |
<artifactId>testng</artifactId> | |
<version>6.8.13</version> | |
<scope>test</scope> | |
</dependency> |
处理好maven依赖后,我们在test目录下创建MockTest文件,class上加入这几条注释,第三条是确定test方法的执行顺序,有jvm,default,name_ascending三种方式,default为系统自己确定的一个顺序,确定方法不明白,但一般不会是你想要的顺序,jvm是每次随机顺序,有时候我们会需要用这个模式,最后的name_ascending为按照test用例的方法名为顺序,这里我们需要测试CRUD操作,用它比较简单。
这里我是统一使用testAB_C()的形式命名test。 A是模块编号按顺序排即可,B是模块内方法的执行顺序,C用来指示方法名,不引起歧义即可,使用驼峰规则。 AB均为0-1-a-z-A-Z的顺序。经测试可行
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MockTest {
写这几个属性用来初始化
private MockMvc mockMvc;
@Autowired
private WebApplicationContext wac;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
接下来就是写test了,但因为我的所有方法中都有调用当前用户打log的操作,所以加了一步用户登录,我使用的是spring security,其他的需要自行处理,反正就是给session或者类似的东西里面塞用户对象就好,我这里思路是调用自己的UserDetailsService实现类中loadUserByUsername(String name)方法来模拟用户登录操作,代码如下
@Before
public void userLoginSpringSecurity() {
//从spring容器中获取UserDetailsService(这个从数据库根据用户名查询用户信息,及加载权限的service)
CustomUserDetailsService userDetailsService = wac.getBean(CustomUserDetailsService.class);
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
//根据用户名username加载userDetails
UserDetails userDetails = userDetailsService.loadUserByUsername("ADMIN");
//根据userDetails构建新的Authentication,这里使用了
//PreAuthenticatedAuthenticationToken当然可以用其他token,如UsernamePasswordAuthenticationToken
PreAuthenticatedAuthenticationToken authentication =
new PreAuthenticatedAuthenticationToken(userDetails, userDetails.getPassword(),userDetails.getAuthorities());
//设置authentication中details
authentication.setDetails(new WebAuthenticationDetails(request));
//存放authentication到SecurityContextHolder
SecurityContextHolder.getContext().setAuthentication(authentication);
}
准备操作完成后就可以开始写Test了,测试controller类,举几个例子就好。这里注意一下我的delete方法,我的参数应该是一个integer数组,但死活就是格式不对,后来我做了一个IntegerRequest类来专门封装Integer和Integer[]形式参数,解决了这个问题。如果你有更好的方式,请留言分享出来,谢谢
/**
* 新增机构,[POST,/group/group]
*/
@Test
public void test40_AddGroup() throws Exception{
Map<String, Object> map = new HashMap<>();
map.put("name", "自动测试_name_doNotUseIt");
map.put("roleIds", new Integer[]{1,2});
mockMvc.perform(post("/group/group")
.contentType(MediaType.APPLICATION_JSON).content(JSONObject.toJSONString(map)))
.andExpect(status().isOk())
.andReturn();
}
/**
* 删除机构,[DELETE,/group/groups]
*/
@Test
public void test44_deleteGroups() throws Exception {
Map<String, Object> map = new HashMap<>();
List<SysGroup> groups = wac.getBean(SysGroupDao.class)
.findByNameLike("%自动测试_name_doNotUseIt%");
List<Integer> idsList = new ArrayList<>();
groups.forEach(sysRole -> idsList.add(sysRole.getId()));
map.put("ids", idsList.toArray(new Integer[]{}));
mockMvc.perform(delete("/group/groups")
.contentType(MediaType.APPLICATION_JSON).content(JSONObject.toJSONString(map)))
.andExpect(status().isOk())
.andReturn();// 返回执行请求的结果
}
/**
* @author : liuqitian
* @date : 2018/7/11 15:43
* @version : V1.2
* 以json格式放置Integer格式和Integer[]格式的信息
*/
public class IntegerRequest {
private Integer id;
private Integer[] ids;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer[] getIds() {
return ids;
}
public void setIds(Integer[] ids) {
this.ids = ids;
}
}
把所有的test写好后,我们可以选中类名MockTest,右键run即可,会按照你指定的顺序执行所有test方法,对比手工测试,这样会省下大量的测试时间