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项目中模拟登录会话,做全流程测试的主要内容,如果未能解决你的问题,请参考以下文章

Junit4单元测试

[转]在Eclipse中使用JUnit4进行单元测试(初级篇)

如何在 JUnit4 中使用休眠测试 DAO

单元测试应用程序生命周期事件

Java单元测试工具:JUnit4

如何解决JUnit4单元测试报错 :method initializationerror not found