前言
最近在进行单元测试的时候使用到了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方法不仅使测试时更加快速准确,也满足了前后端分离测试的需求,
让我们的测试更加简单。这是这一周与同伴们和老师共同学习的结果和总结,感谢我的同伴们和老师。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。