如何在springMVC 中对REST服务使用mockmvc 做测试

 我来答
匿名用户
2016-05-23
展开全部

spring 集成测试中 对mock 的集成实在是太棒了!但是使用请注意一下3个条件。

 

junit 必须使用4.9以上

同时您的框架必须是用spring mvc 

spring 3.2以上才完美支持

 

目前使用spring MVC 取代struts2 的很多,spring MVC 的各种灵活让人无比销魂!所以使用spring MVC吧!

以前在对接口(主要是java服务端提供的接口(一般是:webService,restful))进行测试的中 一般用以下俩种方法。测试流程如图:

1 直接使用httpClient 

    这方法各种麻烦

 

2 使用Spring 提供的RestTemplate

    错误不好跟踪,必须开着服务器

 

使用mockMVC都不是问题了看使用实例:

 

使用事例如下:父类

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.web.context.WebApplicationContext;  

  

@WebAppConfiguration  

@ContextConfiguration(locations = { "classpath:applicationContext.xml",    

"classpath:xxxx-servlet.xml" })  

public class AbstractContextControllerTests {  

  

    @Autowired  

    protected WebApplicationContext wac;  

  

}  

  

子类:  

  

import org.junit.Before;  

import org.junit.Test;  

import org.junit.runner.RunWith;  

import org.springframework.beans.factory.annotation.Autowired;  

import org.springframework.http.MediaType;  

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  

import org.springframework.test.web.servlet.MockMvc;  

import org.springframework.test.web.servlet.setup.MockMvcBuilders;  

  

import com.conlect.oatos.dto.status.RESTurl;  

import com.qycloud.oatos.server.service.PersonalDiskService;  

  

//这个必须使用junit4.9以上才有。  

@RunWith(SpringJUnit4ClassRunner.class)  

public class PersonalDiskMockTests extends AbstractContextControllerTests {  

      

      

    private static String URI = RESTurl.searchPersonalFile;  

  

    private MockMvc mockMvc;  

      

    private String json ="{\"entId\":1234,\"userId\":1235,\"key\":\"new\"}";  

      

    @Autowired  

    private PersonalDiskService personalDiskService;  

  

    @Before  

    public void setup() {  

        //this.mockMvc = webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();  

        this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService).build();  

    }  

  

@Test  

    public void readJson() throws Exception {  

        this.mockMvc.perform(  

                post(URI, "json").characterEncoding("UTF-8")  

                    .contentType(MediaType.APPLICATION_JSON)  

                    .content(json.getBytes()))  

                .andExpect(content().string("Read from JSON: JavaBean {foo=[bar], fruit=[apple]}")  

                    );  

    }  

 

上面是简单的例子,实际使用起来可以稍做修改。记得导入spring -test jar 包。无需额外配置(是不是很方便!)

当然和junit 的assert 一起用的话效果更好。下面贴点例子。copy就能跑。

Java代码  

package com.qycloud.oatos.server.test.mockmvcTest;  

  

import static org.junit.Assert.fail;  

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;  

  

import java.io.UnsupportedEncodingException;  

import java.lang.reflect.Field;  

  

import org.springframework.http.MediaType;  

import org.springframework.test.web.servlet.MockMvc;  

  

import com.conlect.oatos.dto.status.CommConstants;  

import com.conlect.oatos.dto.status.ErrorType;  

import com.conlect.oatos.http.PojoMapper;  

  

public class MockUtil {  

  

    /** 

     * mock 

     *  

     * @param uri 

     * @param json 

     * @return 

     * @throws UnsupportedEncodingException 

     * @throws Exception 

     */  

    public static String mock(MockMvc mvc, String uri, String json)  

            throws UnsupportedEncodingException, Exception {  

        return mvc  

                .perform(  

                        post(uri, "json").characterEncoding("UTF-8")  

                                .contentType(MediaType.APPLICATION_JSON)  

                                .content(json.getBytes())).andReturn()  

                .getResponse().getContentAsString();  

    }  

  

      

    /** 

     *  

     * @param re 返回值 

     * @param object 要转换的对象 

     * @param testName 当前测试的对象 

     */  

    public static <T> void check(String re, Class<T> object,String testName) {  

        System.out.println(re);  

        if (ErrorType.error500.toString().equals(re)) {  

            System.out.println("-----该接口测试失败:-----"  

                    + testName);  

            fail(re);  

        } else if (CommConstants.OK_MARK.toString().equals(re)) {  

            System.out.println("-----该接口测试成功:-----"  

                    + testName);  

        }else{  

            System.out.println("-----re----- :"+re);  

        }  

        if (object != null) {  

            if (re.contains(":")) {  

                try {  

                    T t = PojoMapper.fromJsonAsObject(re, object);  

                    System.out.println("-----该接口测试成功:-----"  

                            + testName);  

                } catch (Exception e) {  

                    System.out.println("-----该接口测试失败:-----"  

                            + testName);  

                    fail(e.getMessage());  

                }  

            }  

        }  

  

    }  

  

  

    /** 

     * 初始化版本信息。每次调用测试用力之前首先更新版本信息 

     * @param mockMvc 

     * @param url 

     * @param fileId 

     * @param class1 

     * @return 

     * @throws UnsupportedEncodingException 

     * @throws Exception 

     */  

    public static <T> Long updateVersion(MockMvc mockMvc, String url,  

            Long fileId, Class<T> class1) throws UnsupportedEncodingException, Exception {  

          

        String re = mock(mockMvc, url, fileId+"");  

          

        T dto = PojoMapper.fromJsonAsObject(re, class1);  

          

Long version = Long.parseLong(dto.getClass().getMethod("getVersion").invoke(dto).toString());     

        System.out.println("version = "+version);  

          

        return version;  

          

    }  

      

}  

 使用如下:

Java代码  

@RunWith(SpringJUnit4ClassRunner.class)  

public class PersonalDiskMockTests extends AbstractContextControllerTests {  

  

    private MockMvc mockMvc;  

  

    private static Long entId = 1234L;  

    private static Long adminId = 1235L;  

  

  

  

  

    @Autowired  

    private PersonalDiskService personalDiskService;  

  

    @Before  

    public void setup() {  

        this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService)  

                .build();  

    }  

  

    /*** 

     * pass 

     * 全局搜索企业文件 

     *  

     * @throws Exception 

     */  

    @Test  

    public void searchPersonalFile() throws Exception {  

  

        SearchFileParamDTO sf = new SearchFileParamDTO();  

        sf.setEntId(entId);  

        sf.setKey("li");  

        sf.setUserId(adminId);  

  

        String json = PojoMapper.toJson(sf);  

  

        String re = MockUtil.mock(this.mockMvc, RESTurl.searchPersonalFile,  

                json);  

        MockUtil.check(re, SearchPersonalFilesDTO.class, "searchPersonalFile");  

  

    }  

}  

 当然@setup里面是每个@test执行时都会执行一次的,所以有些需要每次都实例化的参数可以放进来

如下:

Java代码  

@Autowired  

    private ShareDiskService shareDiskService;  

  

    @Before  

    public void setup() {  

        this.mockMvc = MockMvcBuilders.standaloneSetup(shareDiskService)  

                .build();  

        try {  

            initDatas();  

        } catch (Exception e) {  

            e.printStackTrace();  

        }  

    }  

  

      

  

    private void initDatas() throws UnsupportedEncodingException, Exception {  

        FileIdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,FileId,ShareFileDTO.class);  

        File2IdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,File2Id,ShareFileDTO.class);  

        oldPicFolderVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFolderById,oldPicFolderId,ShareFolderDTO.class);  

    }  

 ok!基本使用大致如此,代码没有些注释,但是很简单,看懂是没问题的。权当抛砖引玉。希望大家加以指正!

btboy1978
2016-07-25 · TA获得超过2015个赞
知道大有可为答主
回答量:2950
采纳率:57%
帮助的人:966万
展开全部
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.web.context.WebApplicationContext;

@WebAppConfiguration
@ContextConfiguration(locations = { "classpath:applicationContext.xml",  
"classpath:xxxx-servlet.xml" })
public class AbstractContextControllerTests {

@Autowired
protected WebApplicationContext wac;

}

子类:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.conlect.oatos.dto.status.RESTurl;
import com.qycloud.oatos.server.service.PersonalDiskService;

//这个必须使用junit4.9以上才有。
@RunWith(SpringJUnit4ClassRunner.class)
public class PersonalDiskMockTests extends AbstractContextControllerTests {


private static String URI = RESTurl.searchPersonalFile;

private MockMvc mockMvc;

private String json ="{\"entId\":1234,\"userId\":1235,\"key\":\"new\"}";

@Autowired
private PersonalDiskService personalDiskService;

@Before
public void setup() {
//this.mockMvc = webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();
this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService).build();
}

@Test
public void readJson() throws Exception {
this.mockMvc.perform(
post(URI, "json").characterEncoding("UTF-8")
.contentType(MediaType.APPLICATION_JSON)
.content(json.getBytes()))
.andExpect(content().string("Read from JSON: JavaBean {foo=[bar], fruit=[apple]}")
);
}

上面是简单的例子,实际使用起来可以稍做修改。记得导入spring -test jar 包。无需额外配置(是不是很方便!)

当然和junit 的assert 一起用的话效果更好。下面贴点例子。copy就能跑。

package com.qycloud.oatos.server.test.mockmvcTest;

import static org.junit.Assert.fail;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;

import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import com.conlect.oatos.dto.status.CommConstants;
import com.conlect.oatos.dto.status.ErrorType;
import com.conlect.oatos.http.PojoMapper;

public class MockUtil {

/**
 * mock
 * 
 * @param uri
 * @param json
 * @return
 * @throws UnsupportedEncodingException
 * @throws Exception
 */
public static String mock(MockMvc mvc, String uri, String json)
throws UnsupportedEncodingException, Exception {
return mvc
.perform(
post(uri, "json").characterEncoding("UTF-8")
.contentType(MediaType.APPLICATION_JSON)
.content(json.getBytes())).andReturn()
.getResponse().getContentAsString();
}


/**
 * 
 * @param re 返回值
 * @param object 要转换的对象
 * @param testName 当前测试的对象
 */
public static <T> void check(String re, Class<T> object,String testName) {
System.out.println(re);
if (ErrorType.error500.toString().equals(re)) {
System.out.println("-----该接口测试失败:-----"
+ testName);
fail(re);
} else if (CommConstants.OK_MARK.toString().equals(re)) {
System.out.println("-----该接口测试成功:-----"
+ testName);
}else{
System.out.println("-----re----- :"+re);
}
if (object != null) {
if (re.contains(":")) {
try {
T t = PojoMapper.fromJsonAsObject(re, object);
System.out.println("-----该接口测试成功:-----"
+ testName);
} catch (Exception e) {
System.out.println("-----该接口测试失败:-----"
+ testName);
fail(e.getMessage());
}
}
}

}


/**
 * 初始化版本信息。每次调用测试用力之前首先更新版本信息
 * @param mockMvc
 * @param url
 * @param fileId
 * @param class1
 * @return
 * @throws UnsupportedEncodingException
 * @throws Exception
 */
public static <T> Long updateVersion(MockMvc mockMvc, String url,
Long fileId, Class<T> class1) throws UnsupportedEncodingException, Exception {

String re = mock(mockMvc, url, fileId+"");

T dto = PojoMapper.fromJsonAsObject(re, class1);

Long version = Long.parseLong(dto.getClass().getMethod("getVersion").invoke(dto).toString());
System.out.println("version = "+version);

return version;

}

}

 使用如下:

@RunWith(SpringJUnit4ClassRunner.class)
public class PersonalDiskMockTests extends AbstractContextControllerTests {

private MockMvc mockMvc;

private static Long entId = 1234L;
private static Long adminId = 1235L;




@Autowired
private PersonalDiskService personalDiskService;

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService)
.build();
}

/***
 * pass
 * 全局搜索企业文件
 * 
 * @throws Exception
 */
@Test
public void searchPersonalFile() throws Exception {

SearchFileParamDTO sf = new SearchFileParamDTO();
sf.setEntId(entId);
sf.setKey("li");
sf.setUserId(adminId);

String json = PojoMapper.toJson(sf);

String re = MockUtil.mock(this.mockMvc, RESTurl.searchPersonalFile,
json);
MockUtil.check(re, SearchPersonalFilesDTO.class, "searchPersonalFile");

}

当然@setup里面是每个@test执行时都会执行一次的,所以有些需要每次都实例化的参数可以放进来

如下:

@Autowired
private ShareDiskService shareDiskService;

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(shareDiskService)
.build();
try {
initDatas();
} catch (Exception e) {
e.printStackTrace();
}
}



private void initDatas() throws UnsupportedEncodingException, Exception {
FileIdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,FileId,ShareFileDTO.class);
File2IdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,File2Id,ShareFileDTO.class);
oldPicFolderVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFolderById,oldPicFolderId,ShareFolderDTO.class);
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
ITjob5
2016-09-14 · TA获得超过209个赞
知道小有建树答主
回答量:399
采纳率:0%
帮助的人:346万
展开全部
spring 集成测试中 对mock 的集成可以,但是使用请注意一下3个条件。
1.junit 必须使用4.9以上
2.同时您的框架必须是用spring mvc
3.spring 3.2以上才完美支持
目前使用spring MVC 取代struts2 的很多,spring MVC 的各种灵活让人无比销魂!所以使用spring MVC吧!
以前在对接口(主要是java服务端提供的接口(一般是:webService,restful))进行测试的中 一般用以下俩种方法。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式