阅读 157

SpringMVC框架如何与Junit整合,看这个就够了

SpringMVC框架如何与Junit整合,看这个就够了

您好,我是码农飞哥,感谢您阅读本文!如果此文对您有所帮助,请毫不犹豫的一键三连吧!本文主要介绍在SpringMVC框架整合Junit框架进行单元测试。闲话少述,让我们直入主题。



文章目录

系统环境

引入依赖

编写单元测试基类

代码说明

MockMvcRequestBuilders

返回结果的content-type是application/json的请求的单元测试

get请求测试

post请求测试

文件上传测试

发送一个json格式的数据到Controller层

返回结果是视图请求的单元测试

直接测试一个service的方法

总结

系统环境

软件 版本

spring-webmvc 4.3.6.RELEASE

spring-test 4.3.6.RELEASE

junit 4.12

引入依赖

 <dependency>

                <groupId>junit</groupId>

                <artifactId>junit</artifactId>

                <version>4.12</version>

                <scope>test</scope>

            </dependency>

  <dependency>

                <groupId>org.springframework</groupId>

                <artifactId>spring-test</artifactId>

                <version>${spring.version}</version>

                <scope>test</scope>

            </dependency>

1

2

3

4

5

6

7

8

9

10

11

12

如上,引入了4个依赖,其中:


junit 是Junit单元测试的基础依赖,它提供了@RunWith和@Test等单元测试必备的注解。<scope>test</scope> 则指明了该依赖的作用范围是test阶段。

spring-test依赖可以理解成是spring框架与junit框架的桥梁。提供了@WebAppConfiguration等注解。

编写单元测试基类

@RunWith(SpringJUnit4ClassRunner.class)

@WebAppConfiguration

@ContextConfiguration("file:src/test/java/spring-config.xml")

@ActiveProfiles("dev")

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)

public abstract class BaseControllerTest  {

    

    protected MockMvc mvc;

    

    @Autowired

    private WebApplicationContext context;

    

   //获取系统上下文 

    protected WebApplicationContext getCtx() {

        return this.context;

    }

//初始化方法

    @Before

    public void setup() throws SQLException {

       this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();

    }

//封装返回结果

    protected String getMockResultStr(MockHttpServletRequestBuilder requestBuilder) {

        try {

            MvcResult mvcResult = this.mockMvc

                    .perform(requestBuilder)

                    .andExpect(status().isOk())

                    .andDo(MockMvcResultHandlers.print())

                    .andReturn();

            MockHttpServletResponse response = mvcResult.getResponse();

            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);

            return response.getContentAsString();

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

代码说明

@RunWith(SpringJUnit4ClassRunner.class) 注解表明使用SpringJUnit4ClassRunner来运行测试用例。

@WebAppConfiguration 注解表明使用的ApplicationContext将是WebApplicationContext类型的;value属性指定web应用的根;同时,他必须与 @ContextConfiguration一同使用。

@ContextConfiguration注解的作用是导入我们需要的配置文件或者类,这里指定了SpringMVC的配置文件

@ActiveProfiles 注解是指定单元测试连接的环境。

@TransactionConfiguration 注解是用与管理spring事务的。

MockHttpServletRequest 类为了模拟HttpServletRequest 对象,可以通过它来设置请求头,这在需要鉴权的接口测试中十分实用。

MockMvc 实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快,不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。

getMockResultStr 方法是封装了公共的测试方法以及响应参数。 其中:

MvcResult mvcResult = this.mockMvc

                    .perform(requestBuilder)

                    .andExpect(status().isOk())

                    .andDo(MockMvcResultHandlers.print())

                    .andReturn();

1

2

3

4

5

perform方法是执行一个RequestBuilder请求,调用Controller的业务处理逻辑。

andExpect 方法是添加执行完成后的断言,添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确,此处是验证状态是否是200

andDo 方法是添加一个结果处理器,比如再此处是andDo(MockMvcResultHandlers.print())输出整个响应结果信息,可以在调试的时候使用。

andReturn:方法是执行完成后返回相应的结果。

MockMvcRequestBuilders

RequestBuilder是用来构建请求的。其提供了一个方法buildRequest(ServletContext servletContext) 用于构建MockHttpServletRequest; 其主要有两个子类MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(文件上传时使用),即用来mock客户端请求需要的所有数据,主要API:

MockHttpServletRequestBuilder get(String urlTemplate, Object… urlVariables): 根据uri模板和uri变量值得到一个GET请求方式的RequestBuilder,如果在controller的方法中method选择的是RequestMethod.GET,那在controllerTest中对应就要使用MockMvcRequestBuilders.get。

post(String urlTemplate, Object… urlVariables):同get类似,但是是POST方法;

通过param 方法来设置请求参数。


返回结果的content-type是application/json的请求的单元测试

get请求测试

get请求的测试就是调用MockMvcRequestBuilders的get方法, 在该方法中传入接口地址。


  MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/v1/works/lineup/set")

                .param("id", "123")

                .param("first_flag", String.valueOf(true));

      String result = getMockResultStr(requestBuilder);

1

2

3

4

post请求测试

post请求的测试就是调用MockMvcRequestBuilders的post方法, 在该方法中传入接口地址。


 MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/v1/blockly/copy")

                .param("id", "1211");

        success(requestBuilder);

1

2

3

文件上传测试

文件上传的测试就是调用MockMvcRequestBuilders的multipart方法, 在该方法中传入接口地址。


  File file = new File(RestArmWorksControllerTest.class.getClassLoader().getResource("20201102172053.png").toURI());

        MockMultipartFile mockMultipartFile = new MockMultipartFile("file", "20201102172053.png", "", new FileInputStream(file));

        MockMultipartHttpServletRequestBuilder servletRequestBuilder = MockMvcRequestBuilders.multipart("/creation/fileUpload.do")

                .file(mockMultipartFile);

        String result = getMockResultStr(servletRequestBuilder);

1

2

3

4

5

发送一个json格式的数据到Controller层

String requestJson = JSONObject.toJSONString(folderInfo);

      MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("//v1/works/save").contentType(MediaType.APPLICATION_JSON).content(requestJson);

1

2

返回结果是视图请求的单元测试

那么,问题来了,如果一个接口的返回结果是视图,那么这个接口的单元测试该如何写呢?比如下面这个接口:


   @RequestMapping(value = "/edit")

   public String edit(ModelMap model, HttpServletRequest request, HttpServletResponse response) {

       Long scriptId = null;

       if (StringUtils.isNotBlank(request.getParameter("scriptId"))) {

           scriptId = Long.parseLong(request.getParameter("scriptId"));

       }

       if (scriptId != null) {

           MallSuperscript mallSuperscript = superScriptService.getScriptById(scriptId);

           model.addAttribute("superScript", mallSuperscript);

       }

       model.addAttribute("scriptTypeMap", ScriptType.toMap());

       logger.info("角标编辑页面返回成功");

       return "manage/superScript/edit";


   }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

这个接口返回的是一个视图,就是名称为edit.jsp页面。它的测试方法可以像下面这样写。


   @Test

    public void testEdit() throws Exception {


        MvcResult mvcResult = mvc

                .perform(

                        get("/manage/tab2/superScript/edit").sessionAttr("adminid", "1111")

                                .sessionAttr("platformid", 1001L).param("scriptId", "1111"))

                .andExpect(status().isOk()).andDo(print()).andReturn();

       

        assertEquals("manage/superScript/edit", mvcResult.getModelAndView().getViewName());

    }

1

2

3

4

5

6

7

8

9

10

11

通过mvcResult.getModelAndView().getViewName()获取视图的名称。


直接测试一个service的方法

上面的那些测试针对的都是Controller层的接口,那么如果要测试一个service层的方法,该如何处理呢?


public class MallMailJobTest extends BaseControllerTest {


    private MallMailJob mallMailJob;


    @Override

    @Before

    public void setup() throws SQLException {

        super.setup();

        mallMailJob = getCtx().getBean(MallMailJob.class);

    }


    /**

     * 

     * @throws Exception

     */

    @Test

    public void testExecute() throws Exception {

        mallMailJob.execute();

    }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

被测试的MallMailJob类也可以通过@Autowired 注解直接注入进Spring IOC容器中。拿到被测试类的实例之后就可以直接调用被测试的方法,是不是灰常的简单呀。



总结

本文详细介绍在SpringMVC任何使用Junit框架。首先介绍了如何引入依赖,接着介绍了编写一个测试基类,并且对其中涉及的各个注解做了一个详细说明。最后就是罗列了各种测试情况。

————————————————

版权声明:本文为CSDN博主「码农飞哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u014534808/article/details/116380284


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐