SpringMVC框架整合Junit进行单元测试(案例详解)

作者:码农飞哥 时间:2022-04-10 20:53:37 

本文主要介绍在SpringMVC框架整合Junit框架进行单元测试。闲话少述,让我们直入主题。

SpringMVC框架整合Junit进行单元测试(案例详解)

系统环境

软件版本
spring-webmvc4.3.6.RELEASE
spring-test4.3.6.RELEASE
junit4.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>

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

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

  2. 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.  @RunWith(SpringJUnit4ClassRunner.class) 注解表明使用SpringJUnit4ClassRunner来运行测试用例。

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

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

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

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

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

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

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


MvcResult mvcResult = this.mockMvc
                   .perform(requestBuilder)
                   .andExpect(status().isOk())
                   .andDo(MockMvcResultHandlers.print())
                   .andReturn();
  1. perform方法是执行一个RequestBuilder请求,调用Controller的业务处理逻辑。

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

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

  4. 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。

  • MockHttpServletRequestBuilder.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);

post请求测试

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


MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/v1/blockly/copy")
               .param("id", "1211");
       success(requestBuilder);

文件上传测试

文件上传的测试就是调用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);

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


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

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

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


@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";

}

这个接口返回的是一个视图,就是名称为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());
   }

通过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();
   }

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

总结

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

来源:https://blog.csdn.net/u014534808/article/details/116380284

标签:SpringMVC,整合,Junit
0
投稿

猜你喜欢

  • 将本地的jar包打到Maven的仓库中实例

    2022-08-29 13:38:28
  • 安卓Android6.0权限动态获取操作示例

    2023-01-26 22:56:43
  • Java框架设计灵魂之反射的示例详解

    2023-06-13 21:34:34
  • java中Swing会奔跑的线程侠

    2021-12-14 23:47:36
  • 初识Java基础之数据类型与运算符

    2021-10-13 12:20:32
  • java实现简单超市管理系统

    2022-04-03 07:41:04
  • SpringBoot 创建容器的实现

    2022-04-03 08:41:02
  • Android自定义控件之广告条滚动效果

    2022-01-27 05:57:45
  • Springboot Session共享实现原理及代码实例

    2022-12-16 03:29:52
  • springboot中request和response的加解密实现代码

    2023-05-27 16:46:27
  • Java使用过滤器防止SQL注入XSS脚本注入的实现

    2021-09-14 18:17:19
  • 关于Java虚拟机HotSpot

    2022-10-28 18:36:01
  • kotlin实现强制下线功能

    2023-06-13 12:35:08
  • IDEA集成JProfiler11可视化工具的详细流程(安装、集成、测试)

    2021-12-12 04:05:35
  • jenkins+Maven从SVN上构建项目的方法

    2022-07-09 04:42:37
  • 使用java实现各种数据统计图(柱形图,饼图,折线图)

    2022-03-09 22:12:50
  • Java之Mybatis多层嵌套查询方式

    2023-06-17 11:48:52
  • Java swing五子棋的实现方法

    2021-06-01 15:25:20
  • C#实现控制线程池最大数并发线程

    2023-02-23 14:50:43
  • java框架之maven是用来做什么的

    2023-04-20 21:59:43
  • asp之家 软件编程 m.aspxhome.com