SpringMVC 之MockMVC注释 详解

SpringMVC的 Mockmvc的优势:

所谓的Mock测试,就像servletAPI中的HttpServletRequest对象是Tomcat容器生成的。我们无法手动的new出来,于是就有了所谓的Mock测试

对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如启动速度慢,测试验证不方便,依赖网络环境等,这样会导致测试无法进行,为了可以对Controller进行测试,可以通过引入MockMVC进行解决。

pom.xml 依赖

 <!-- spring-test -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-test</artifactId>              <version>${spring-framework.version}</version>              <scope>test</scope>          </dependency>            <!-- junit -->          <dependency>              <groupId>junit</groupId>              <artifactId>junit</artifactId>              <version>4.11</version>              <scope>test</scope>          </dependency>

常用的注释:

@RunWith(SpringJUnit4ClassRunner.class)

使用Spring-Test框架, 在使用所有注释前必须使用 @RunWithSpringJUnit4ClassRunner.class),让spring test 运行于Spring测试环境, 通俗的理解就是指定测试类使用某个运行器.

@WebAppConfiguration

使用这个注释会在执行单元测试的时候真实的启动一个web服务,然后开始调用Controller的Rest API,待单元测试执行完后再将web服务停止.

@ContextConfiguration

指定需要加载的spring配置文件的地址, 可以有多种方式. 如果有多个配置文件,可以用括号括起来,controller,component等都是使用注解,需要注解指定spring的配置文件,扫描相应的配置,将类初始化等。

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

配置事务的回滚 ,对数据库的增删改都会回滚,便于测试用例的循环利用

@Transactional

非必须,是和@TestExecutionListeners中的TransactionalTestExecutionListener.class配合使用,用于保证插入的数据库中的测试数据,在测试完后,事务回滚,将插入的数据删除,保证数据库的干净。如果没有显示的指定@Transactional,那么插入到数据库中的数据就是真实数据。

@Mock

MockMvc模拟MVC对象,通过MockMvcBuilders.webAppContextSetup(this.wac).build()进行初始化

@InjectMocks

需要将Mock对象注入的对象, 可以是被测的Controller

@Before

在每个Test方法之前运行的方法,一般用来初始化方法

mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();

@Test

执行测试

@Autowired

为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;按照类型(byType)注入.默认情况下它要求依赖对象必须存在

@After

在每个测试方法后执行,在方法执行完成后要做的事情

实际运用:

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.transaction.TransactionConfiguration;  import org.springframework.test.context.web.WebAppConfiguration;  import org.springframework.transaction.annotation.Transactional;  import org.springframework.web.context.WebApplicationContext;    //这个必须使用junit4.9以上才有  @RunWith(SpringJUnit4ClassRunner.class)  //单元测试的时候真实的开启一个web服务  @WebAppConfiguration  //配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用  @TransactionConfiguration(transactionManager="transactionManager",defaultRollback=true)  @Transactional  //指定需要加载的spring配置文件的地址, 可以有多种方式. 如果有多个配置文件  @ContextConfiguration(locations = {"classpath:spring.xml","classpath:spring-hibernate.xml"})  public class ControllerTest {          MockMvc mockMvc;        @Autowired    //spring 自动注入      WebApplicationContext wac;        @Autowired      MyWebConfig myWebConfig=new MyWebConfig();         @Before //每次Test方法之前运行的方法,常用于初始化操作      public void setUp(){          System.out.println("----------Before----------");         DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);          //mockMvc= MockMvcBuilders.standaloneSetup(myWebConfig).build();          mockMvc = builder.build();      }        @Test      public void testUserController() throws Exception {          this.mockMvc.perform(get("/deviceevent/list") //                   .accept(MediaType.parseMediaType("text/html;charset=UTF-8")))                  .andExpect(status().isOk()) // 验证status code                  .andExpect(model().size(1)) //      }        @After      public void testAfter(){          System.out.println("-----------After-------------- ");      }       }

为什么要做事务回滚?

在写单元测试的时候,一般是对数据库进行增删改查的操作,这个时候,如果之前删除了某条记录,自然后面的程序就找不到这条记录,所以可以通过配置spring的事务管理或者测试框架来回滚,减少工作量,同时也保证每一次测试的数据都是干净的。

测试是保证软件质量的关键, mock是为了测试Web项目不需要启动web server等服务项目,我们只需要一些Servlet相关的模拟对象,比如:MockMVC,MockHttpServletRequest,MockHttpServletResponse,MockHttpSession等。在Spring里,我们使用@WebAppConfiguration指定加载的ApplicationContext是一个WebAppConfiguration即可对某一模块进行单独测试.