6

前言

最近在进行单元测试的时候使用到了mock方法,同时通过老师的讲解也大致理解了单元测试的过程,下面对mock进行一些总结。

Mock

mock中文翻译为虚假的,不真实的。
人如其名,mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mock对象来模拟对象的行为。
什么是复杂的对象

  class A 依赖 class B
    

  class B 依赖 class C和class D
    

  class C 依赖 ...
    

  class D 依赖 ...

被测对象依赖的对象构造复杂。我们想对class A进行单元测试,需要构造大量的class B、C、D等依赖对象,他们的构造过程复杂,这时我们可以利用mock去构造虚拟的class B、C、D对象用于class A的测试,因为我们只是想测试class A的行为是否符合预期,我们并不需要测试依赖对象。
另外,如果需要引入的的模块开发尚未完成,我们又需要在单元测试中使用,我们也可以用Mock方法来代替。

Mock的框架

我们了解完Mock后,那什么是Mockito,什么是MockMvc呢,他们都是Mock的框架,其中,Mockito是Mock应用最广泛的框架。

MockMvc

MockMvc实现对Http请求的模拟,可以方便对Controller进行测试,使得测试速度快、不依赖网络环境。我们不用再依赖前端的代码,从而实现了前后端分离,独立测试。
常见使用方式
1 MockMvcBuilder构造MockMvc的构造器

2 MockMvcRequestBuilders创建请求request

3 mockMvc调用perform,执行一个request请求,调用controller的业务处理逻辑,返回ResultActions

4 对结果进行验证
我们看教程中的代码其实是合在一起去写

@Test
public void save() throws Exception {
    String url = "/Student"; 
    JSONObject studentJsonObject = new JSONObject(); 
    JSONObject klassJsonObject = new JSONObject(); 

    studentJsonObject.put("sno", "学号测试"); 
    studentJsonObject.put("name", "姓名测试"); 
    klassJsonObject.put("id", -1); 
    studentJsonObject.put("klass", klassJsonObject); 

    MvcResult mvcResult = this.mockMvc.perform( 
            MockMvcRequestBuilders.post(url)
                    .content(studentJsonObject.toString())
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
    ).andExpect(MockMvcResultMatchers.status().is(201))
            .andReturn();
}

我们将其中的测试拆分出来看看

// 构建请求
MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post(url)
            .content(studentJsonObject.toString())
            .contentType(MediaType.APPLICATION_JSON_UTF8);

// 发送请求,获取请求结果
ResultActions perform = mvc.perform(request);

// 请求结果校验
perform.andExpect(MockMvcResultMatchers.status().is(201));

MvcResult mvcResult = perform.andReturn();

Mockito

Mockito可以理解为mock input to output。我们只关心input与output,也就是输入与输出,中间的过程实现我们并不关心,从而实现了对复杂对象的简单化。
前端传给c层我们利用MockMvc模拟,那测试C层与M层的数据传输我们可以利用Mockito来模拟。
我们常用方法如下

Mockito.when( 
            studentService.save(
                    Mockito.any(Student.class)))
            .thenReturn(returnStudent);

当调用studentService.save()方法时并传入一个Student类型的参数,就去返回returnStudent。这个的returnStudent使我们去设定的。
我们的save方法定义就是传入一个Student类型的参数,为什么后面还会设定Mockito.any(Student.class)呢,这是因为函数可能重载,我们规定传入参数防止产生歧义,当然这里我们没有进行重载。

总结

Mock方法不仅使测试时更加快速准确,也满足了前后端分离测试的需求,
让我们的测试更加简单。这是这一周与同伴们和老师共同学习的结果和总结,感谢我的同伴们和老师。


小强Zzz
1.2k 声望32 粉丝

« 上一篇
什么是JPA
下一篇 »
spy间谍函数