Java 单测之Mock

一.前言

集成的单元测试和集成测试有什么区别呢?

  集成测试(Integration Testing):是在单元测试的基础上,将所有模块按照概要设计要求组装成为一个子系统或者系统,进行集成测试。一些模块虽然能够单独工作,但并不能保证连接起来也能正常的工作,程序在某些局部反映不出来的问题,在全局上很可能暴漏出来,因此集成测试十分必要。
  集成的单元测试:按字面意思的理解,就是对该集成类进行单元测试。单元测试就是对已经实现的软件最小单元进行测试以保证构成软件系统的各个单元的质量。这么说来,在此处集成的单元测试和集成测试并无区别吗?
  No~ 区别还是有的,集成的单元测试,首先是个单元测试,然后是对集成类进行单元测试,也就是说只测试该类的逻辑,而不用关注他所依赖的类是否正确实现。如何不关注依赖类的是否正确实现呢?这就是接下来我要介绍的Mock。

二.为什么需要mock

  我们在做测试的时候,往往会发现我们要测试的类或方法会引用很多外部依赖的对象,而我们没法控制这些外部依赖的对象,为了解决这个问题,我们需要用到Mock来模拟这些外部依赖的对象,从而控制它们。举个例子,service调用dao,即service依赖dao,我们可以用mock来模拟真实的dao调用,从而达到测试service的目的。
  模拟对象(Mock Object)可以取代真实对象的位置,用于测试一些与真实对象进行交互或依赖于真实对象的功能,模拟对象背后的目的就是创建一个轻量级的,可以控制的对象来代替测试中需要的真实对象,模拟真实对象的行为和功能。

mock对象使用范畴
1.真实对象具有不可确定的行为,产生不可预测的效果。
2.真实对象很难被创建的。
3.真实对象的某些行为很难被触发。
4.真实对象实际上还不存在的。

三.常见的mock框架

  • jmock:通过mock对象来模拟一个对象的行为,从而隔离开我们不关心的其他对象,使得测试变得简单。缺点:在执行前记录期望行为,显得很繁琐。
  • Mockito:Mockito通过在执行后校验哪些函数已经被调用,消除了对期望行为的需要,API非常简洁。缺点:对于静态函数、构造函数、私有函数等还是无能为力。
  • powermock:PowerMock是在Mockito的基础上做出的扩展。通过提供定制的类加载器以及一些字节码篡改技巧的应用,PowerMock 实现了对静态方法、构造方法、私有方法以及 Final 方法的模拟支持,对静态初始化过程的移除等强大的功能。缺点:会对字节码篡改,即测试时的字节码与平时编译出来的字节码是不一样的,而很多统计单元测试覆盖率的插件是以字节码来统计的,所以PowerMock编写的测试程序不能被统计进覆盖率。

推荐Mockito和powermock

四.Mockito简单介绍

一般使用Mockito需要执行以下步骤:
1.模拟并替换测试代码中外部依赖。
2.执行测试代码。
3.验证测试代码是否被正确的执行

 

Mock执行步骤.png

使用注解(@Mock、@InjectMocks等)的话,必须实例化mock对象,有两种方式实例化mock对象:

  • @RunWith(MockitoJUnitRunner.class)
  • MockitoAnnotations.initMocks(this)

当我们需要配置某个方法的返回值时,Mockito提供了链式的API供我们方便的调用:

  • when(mockObject.someMethod()).thenReturn(...)
    用来定义当条件满足时函数的返回值。
  • when(mockObject.someMethod()).thenReturn(...).thenReturn(...)
    用来定义多个返回值的情况。
  • doReturn(...).when(mockObject.someMethod())
  • when(mockObject.someMethod()).thenThrow(new Runtime
    Exception())
    执行某方法时抛出异常。
  • doThrow(new RuntimeException()).when(mockObject.someMethod())
  • 对void方法进行预期设定
    1.doNothing().when(mock.someMethod())
    2.doThrow(new RuntimeException()).when(mock.someMethod())
    3.doNothing().doThrow(new RuntimeException()).when(mock.someMethod())
  • Mockito会自动记录自己的交互行为,可以用verify(…).methodXxx(…)语法来验证Xxx()方法是否按照预期进行了调用
    1.验证调用次数:verify(mockObject,times(n)).someMethod(argument);//n为被调用的次数
    2.验证超时:verify(mockObject, timeout(100)).someMethod();
    3.既验证调用次数,又验证是否超时:verify(mockObject, timeout(100).times(1)).someMethod();

需注意:

  • 对于final、static、私有方法,Mockito 无法对其 when(…).thenReturn(…) 操作。

五.对于final、static的PowerMock

https://my.oschina.net/jackieyeah/blog/157076

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ant Design Pro v4 是一个基于 Ant Design 设计语言的企业级中后台前端/设计解决方案,其中包含了一些用于数据模拟的 mock 功能。在 Pro v4 中,mock 数据是通过 umi-request 库来实现的。 要在 Ant Design Pro v4 中使用 mock 功能,你可以按照以下步骤进行操作: 1. 在 `src` 目录下创建一个名为 `mock` 的文件夹。 2. 在 `mock` 文件夹中创建一个名为 `api.ts` 的文件,用于编写接口的 mock 数据。 3. 在 `api.ts` 文件中,你可以使用 umi-request 提供的 `extend` 方法来创建一个请求实例,并通过 `mock` 方法来定义接口的 mock 数据。例如: ```typescript import { extend } from 'umi-request'; const request = extend({ prefix: '/api', timeout: 1000, }); export default { 'GET /api/user': { id: 1, name: 'John Doe', }, 'POST /api/login': (req, res) => { const { username, password } = req.body; if (username === 'admin' && password === '123456') { res.send({ status: 'ok', message: 'Login successful!', }); } else { res.send({ status: 'error', message: 'Invalid username or password!', }); } }, 'PUT /api/user/:id': (req, res) => { const { id } = req.params; const { name } = req.body; res.send({ id, name, }); }, }; ``` 在上面的例子中,我们定义了三个接口的 mock 数据:`GET /api/user`、`POST /api/login` 和 `PUT /api/user/:id`。 4. 在 `src` 目录下的 `models` 文件夹中创建一个名为 `mock.ts` 的文件,并在该文件中导入 `api.ts` 中定义的 mock 数据。例如: ```typescript import api from '@/mock/api'; const enableMock = true; // 是否开启 mock 功能 if (enableMock) { Object.keys(api).forEach((key) => { const [method, path] = key.split(' '); const [mockMethod, mockPath] = method.split('_'); if (mockMethod && mockPath) { umiMocker(mockMethod.toUpperCase(), mockPath, api[key]); } }); } ``` 在上面的例子中,我们通过遍历 `api.ts` 中定义的 mock 数据,并使用 `umiMocker` 方法来注册 mock 接口。 5. 在 `src/app.tsx` 文件中,将 `import './mock';` 添加到文件开头,以确保 mock 数据在应用启动时被加载。例如: ```typescript import './mock'; ``` 完成以上步骤后,当你在开发环境下运行 Ant Design Pro v4 时,接口请求将会被拦截并返回 mock 数据。 请注意,以上只是一个简单的示例,你可以根据自己的需求来编写更复杂的 mock 数据。另外,需要注意的是,在生产环境下是不会启用 mock 功能的,mock 数据只会在开发环境中生效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值