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.remove(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請求的。

 

以上是項目中一點記錄,各位網友有更好的建議,歡迎拍磚。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM