junit4单元测试--web项目中模拟登录会话,做全流程测试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了junit4单元测试--web项目中模拟登录会话,做全流程测试相关的知识,希望对你有一定的参考价值。
junit4相对于junit3,基于注解的方式写单元测试用例,使用过程中方便很多。如下缩写均是代码片段,摘录其中关键部分,重要是理解其中知识点。
一、编写测试用例基类
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml", "file:src/main/webapp/WEB-INF/spring-servlet.xml", "file:src/main/webapp/WEB-INF/conf/spring-redis.xml", "file:src/main/webapp/WEB-INF/conf/spring-resttemplate.xml"}) public abstract class BaseJunit { /** * wac */ @Autowired private WebApplicationContext wac; /** * MockMvc */ private MockMvc mockMvc; protected WebApplicationContext getWac() { return this.wac; } protected MockMvc getMockMvc() { return this.mockMvc; } /** * 初始化mocMvc * * @see */ @Before public void setUp() { this.mockMvc = webAppContextSetup(this.wac).build(); }
...... }
@RunWith(SpringJUnit4ClassRunner.class) 指定采用Spring的运行环境
@WebAppConfiguration 用来声明这是一个web测试环境
@ContextConfiguration 用来指定加载项目的配置文件
二、抽出web系统登录方法
public abstract class BaseLoginJunit extends BaseJunit { /** * MockMvc */ private MockHttpSession session; protected MockHttpSession getSession() { return session; } /** * 测试前,初始化系统登录 * * @see */ @Before public void setUp() { super.setUp(); this.session = (MockHttpSession)getLoginSession(); } /** * 完成登录功能,返回当前登录会话 * * @return HttpSession * @see */ private HttpSession getLoginSession() { String url = "/xxx/login"; String params = "{\"userName\":\"xxx\",\"password\":\"xxx\",\"verifyCode\":\"xxx\"}"; MvcResult result = null; try { result = getMockMvc().perform( MockMvcRequestBuilders.post(url).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).content( params)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn(); } catch (Exception e) { e.printStackTrace(); } return result.getRequest().getSession(); }
...... }
三、编写spring控制器测试方法
@FixMethodOrder(MethodSorters.NAME_ASCENDING) // 指定按字母顺序执行测试用例 public class ResourceControllerTest extends BaseLoginJunit { /** * res id list */ private static List<String> RES_LIST = new ArrayList<>(); /** * 测试 getResource * * @see */ @Test public void testGetResource() { String url = "/xxx/get"; MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); this.setPage(map); get(url, map); } /** * 测试 add * * @see */ @Test public void testAddResource() { String url = "/xxx/add"; ResourceBean bean = new ResourceBean(); ResourceBean anotherBean = new ResourceBean(); bean.setResName("test res1"); anotherBean.setResName("test res2"); MvcResult result = post(url, JSONObject.toJSONString(bean)); ReturnVal returnVal = this.getReturnVal(result); RES_LIST.add(returnVal.getData().getId()); MvcResult anotherResult = post(url, JSONObject.toJSONString(childBean)); ReturnVal anotherReturnVal = this.getReturnVal(anotherResult); RES_LIST.add(anotherReturnVal.getData().getId()); } /** * 测试updateResource * * @see */ @Test public void testBupdateResource() { String url = "/xxx/update"; ResourceBean bean = new ResourceBean(); bean.setId(RES_LIST.get(0)); bean.setResName("test res1"); MvcResult result = post(url, JSONObject.toJSONString(bean)); assertEquals(AbstractController.STATUS_SUCCESS, getReturnVal(result).getStatus()); } /** * 测试delResource * * @see */ @Test public void testCdelResource() { String url = "/xxx/delete"; MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("id", RES_LIST.get(0)); MvcResult result = get(url, map); assertEquals(AbstractController.STATUS_SUCCESS, getReturnVal(result).getStatus()); } /** * 测试batchDelResource * * @see */ @Test public void testDbatchDelResource() { String url = "/xxx/batchDel"; MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); StringBuilder params = new StringBuilder(); for (int i = 0; i < RES_LIST.size(); i++ ) { if (i == RES_LIST.size() - 1) { params.append(RES_LIST.get(i)); } else { params.append(RES_LIST.get(i)).append(","); } } map.add("id", params.toString()); MvcResult result = get(url, map); assertEquals(AbstractController.STATUS_SUCCESS, getReturnVal(result).getStatus()); } }
以上测试用例中,@FixMethodOrder很关键,因为增、删、改、查需要指定测试的顺序。MethodSorters.NAME_ASCENDING指定按字母顺序执行测试用例,注意test后的第一个字母,按照A、B、C、D来的。在junit中,@FixMethodOrder的值有三种选择,分别如下:
MethodSorters.DEFAULT:按默认顺序,具体怎样的顺序不确定。
MethodSorters.JVM:按JVM得到的方法顺序。
MethodSorters.NAME_ASCENDING:按字母顺序。
用例中,需要测试用例按指定顺序执行,测试时使用MethodSorters.JVM,有解释说,这个是按照方法中方法的顺序执行,实际测试不可行。最终选择MethodSorters.NAME_ASCENDING按字母指定顺序。几个用例中涉及到数据依赖的问题,在这里,把依赖的数据都放入静态的RES_LIST中,供各方法共享。
ps:
1、以上使用过程中,使用setUp初始化登录,而junit中每个test用例执行前,都会调用setUp方法,导致登录功能频繁调用,实际上只调用一次就好。这个问题有待解决。不过按以上方法,从模拟登录,到指定测试流程均可进行,一般的测试都可以满足。
2、这里描述的只是控制器部分的测试,只是测试http请求的。
以上是项目中一点记录,各位网友有更好的建议,欢迎拍砖。
以上是关于junit4单元测试--web项目中模拟登录会话,做全流程测试的主要内容,如果未能解决你的问题,请参考以下文章