一、本节主要记录模拟测试、单元测试:

二、mock 测试

1.1什么是Mock?

在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的假的对象。比如:对象B依赖于对象A,但是A代码还没写是一个空类空方法不能用,我们来mock一个假的A来完成测试。

/**
 * @author Levi
 * @date 2019/10/4 21:09
 */
//@Transactional
@Slf4j
@SpringBootTest
public class MockTest {

    private MockMvc mockMvc;

    //它是不在spring容器中的,需要手动引入
    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(new AnimalController()).build();
    }

    @Test
    public void saveArticle() throws Exception {
        //直接将前面请求的例子粘贴过来会自动分行
        String article = "{\n" +
                "    \"id\": 1,\n" +
                "    \"name\": \"pig\",\n" +
                "    \"type1\": \"\",\n" +
                "    \"birthDate\":\"2019-10-04T05:10:10\",\n" +
                "    \"animalList\":[{\"name\":\"dog\",\"type\":5},{\"name\":\"dog\",\"type\":10}]\n" +
                "}";
        MvcResult result = mockMvc.perform(
                MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/animals")
                        .contentType("application/json").content(article))
                .andExpect(MockMvcResultMatchers.status().isOk())//返回状态200为成功
                .andExpect(MockMvcResultMatchers.jsonPath("$.data.name").value("pig"))//返回属性name为pig
                .andExpect(MockMvcResultMatchers.jsonPath("$.data.animalList[0].type").value(5))//返回属性type需要为5
                .andDo(print())
                .andReturn();

        log.info(result.getResponse().getContentAsString());

    }
}

测试代码;

返回结果;

2.1 @SpringBootTest 注解说明:

是用来创建Spring的上下文ApplicationContext,保证测试在上下文环境里运行。单独使用@SpringBootTest不会启动servlet容器。所以只是用SpringBootTest 注解,不可以使用@Resource和@Autowired等进行依赖注入(准确的说是可以使用,但被注解的bean为null)。

2.2 @Transactional

可以使单元测试进行事务回滚,以保证数据库表中没有因测试造成的垃圾数据,再就是保证单元测试可以反复执行;
不要在 Spring Boot 集成测试中使用 @Transactional

不推荐使用,他会删表,不会删除数据,他的事务是在内存中进行的,模拟的结果是不正确的,和真实环境有差距的;

2.3 MockMvc有以下几个基本的方法:

  • perform : 执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理。
  • contentType:发送请求内容的序列化的格式,"application/json"表示JSON数据格式
  • andExpect: 添加RequsetMatcher验证规则,验证控制器执行完成后结果是否正确,或者说是结果是否与我们期望(Expect)的一致。
  • andDo: 添加ResultHandler结果处理器,比如调试时打印结果到控制台
  • andReturn: 最后返回相应的MvcResult,然后进行自定义验证/进行下一步的异步处理

3.1怎样在真实的servlet容器中运行

在测试类上面额外加上这样两个注解,mockMvc使用@Resource自动注入,删掉Before注解及setUp函数

添加

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
注解后,即在spring中运行;

3.1 @RunWith注解

RunWith方法为我们构造了一个的Servlet容器运行运行环境,并在此环境下测试。然而为什么要构建servlet容器?因为使用了依赖注入,注入了MockMvc,在上个例子里面是我们自己构建的。而@AutoConfigureMockMvc注解,该注解表示 MockMvc由我来构建,你只负责用就可以了。这种写法是为了让测试在Spring容器环境下执行。Spring的容器环境是啥呢?比如常见的 Service  Dao 都是Spring容器里的bean,装载到容器里面,都可以使用@Resource和@Autowired来引用。

注入并使用了@Runwith,少了这个注解,service注入不进去,会报空指针

4、轻量级测试(注入指定的Controller和service进行测试)

1、在RunWith的AutoConfigureMockMvc注解的共同作用下,启动了SpringMVC的运行容器。并且把项目中所有的@Bean全部都注入进来。把所有的bean都注入进来是不是略显臃肿,真实的单元测试有可能上千个,这样会拖慢单元测试的效率。如果我只是想测试一下web层,或者说的控制层Controller,怎么办?或者说我只想测试一下ArticleRestController,你不要把应用中所有的bean都注入。

/**
 * 在轻量级容器中的测试
 * @author Levi
 * @date 2019/10/4 21:09
 */
//@Transactional
@Slf4j
//@SpringBootTest
@WebMvcTest      //注入所有controller  甚至可以注入指定controller @WebMvcTest(AnimalController.class)
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
public class MockTestSimple {

    @Resource
    private MockMvc mockMvc;
    @MockBean
    private AnimalService animalService;
    @Test
    public void saveArticle() throws Exception {
        String animal = "{\n" +
                "    \"id\": 1,\n" +
                "    \"name\": \"pig\",\n" +
                "    \"type\": \"\",\n" +
                "    \"birthDate\":\"2019-10-04T05:10:10\",\n" +
                "    \"animalList\":[{\"name\":\"dog\",\"type\":5},{\"name\":\"dog\",\"type\":10}]\n" +
                "}";

        log.error("animal"+animalService.saveAnimal(null));
        ObjectMapper objectMapper = new ObjectMapper();
        Animal animalObj = objectMapper.readValue(animal,Animal.class);

        //打桩--当controller调用改service时,模拟返回一个ok
        when(animalService.saveAnimal(animalObj)).thenReturn("ok");

        MvcResult result = mockMvc.perform(
                MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/animals")
                        .contentType("application/json").content(animal))
                .andExpect(MockMvcResultMatchers.status().isOk())//返回状态200为成功
                .andExpect(MockMvcResultMatchers.jsonPath("$.data.name").value("pig"))//返回属性name为pig
                .andExpect(MockMvcResultMatchers.jsonPath("$.data.animalList[0].type").value(5))//返回属性type需要为5
                .andDo(print())
                .andReturn();

        log.info(result.getResponse().getContentAsString());
    }
}

可以查看到电泳到的sevice 不是“animal测试”,而是“ok”


												

最新文章

  1. 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)
  2. PTGM and APTM
  3. GET DIAGNOSTICS Syntax
  4. jQuery 制作逼真的日历翻转效果的倒计时
  5. YSPASYS 中小型企业简单员工评价考核系统
  6. ubuntu导出文件
  7. js获取url传递参数的写法
  8. Hdu 5050 Divided Land
  9. Jquery ajaxSubmit()的浏览器兼容问题
  10. 【SqlServer系列】表连接
  11. 从Javascript单线程谈Event Loop
  12. php银联网页支付实现方法
  13. DCOS实践分享(6):基于DCOS的大数据应用分享
  14. python 的 virtualenv 环境搭建及 sublime 手动创建运行环境
  15. thinkphp51初始化方法initialize
  16. [转]php hash_pbkdf2 和 node.js crypto.pbkdf2
  17. 2017 Python最新面试题及答案16道题
  18. sublime将python的运行结果在命令行显示
  19. 安装Helm
  20. ALGO-157_蓝桥杯_算法训练_阶乘末尾(高精度)

热门文章

  1. Netty源码剖析-构建链接
  2. 粒子群算法(PSO)
  3. Is It A Tree? POJ - 1308(并查集判树)
  4. Centos安装elasticsearch,php连接使用
  5. Linux(CentOS7)系统中部署Django web框架
  6. command not found 的解决&&解释
  7. Grace模式、Saint模式
  8. 由[].slice.call()引发的思考
  9. winfrom_关于打印小票
  10. Arcgis for js加载百度地图