首页 > 编程知识 正文

mock性能测试,mock接口测试

时间:2023-05-06 18:04:24 阅读:159964 作者:2134

一. Mock测试1、什么是Mock测试

Mock测试是一种在测试过程中为不容易构建或不容易获得的复杂对象(如JDBC的ResultSet对象)创建虚拟对象(Mock对象)以进行测试的测试方法。

2、为什么要进行Mock测试

Mock是为了解决不同单元之间的耦合导致开发测试困难的问题。 所以,Mock既出现在单元测试中,也出现在集成测试、系统测试中。 Mock的最大功能是分解单元测试的结合。 如果代码依赖于其他类或接口,请模拟这些依赖关系并验证被调用依赖关系的行为。 例如,代码就有这样的依赖:

如果需要测试类a,如果没有Mock,则需要构建整个依赖树,但使用Mock可以按如下方式分解结构:

3、Mock对象适用场景

)1)需要将当前的被测单元及其依赖模块独立,建立独立的测试环境。 不关注被测定单元的依存对象,只关注被测定单元的功能逻辑。

---例如,被测代码中需要依赖第三方接口的返回值进行逻辑处理,由于网络和其他环境因素,调用第三方往往会出现中断或失败,导致无法测试被测单元。 在这种情况下,可以使用mock技术使被测单元和依赖模块独立进行测试。

)2)被测单元所依赖的模块尚未开发出来,被测单元需要依赖模块的返回值进行后续处理。

1 )在前后端项目中,在后端接口开发完成之前,对接口进行协作;

2 )所依赖的上游项目接口尚未开发,需要接口联合测试;

---例如,服务层的代码包括对Dao层的调用,但尚未实现Dao层代码

)3)被测单元依赖的对象难以模拟或结构复杂。

-----比如,支付宝支付的异常条件有很多,但模拟这个异常条件很复杂或者是无法模拟的。 例如,无法查询符合成本效益的订单结果,在测试环境中进行模拟。

4、Mock测试的优势

)1)团队可以并行工作

有了Mock,前后的终端用户只需定义接口文档就可以开始并行工作,互不影响,只在最后的协同阶段进行紧密的交互; 如果后端和后端之间存在接口耦合,同样可以通过Mock解决; 如果在测试过程中没有准备好依赖接口,也可以使用Mock,一个团队不会等待另一个团队。 如此一来,开发自检阶段可以提前,缺陷发现的时间也提前,有利于保证产品整体的质量和进度。

)2)开启TDD模式,即测试驱动开发

单元测试是TDD实现的基础,TDD经常会遇到协同模块尚未开发的情况,但只要有mock,这些都不是问题。 定义接口后,测试人员可以创建Mock,将接口添加到自动化测试环境中,并提前创建测试。

)3)可以模拟无法访问的资源

例如,如果需要调用“墙”外的资源以便于自己调试,则可以自己进行Mock。

(4)隔离系统

为了得到某个响应,需要调用post请求以确认当前系统是否能够正确处理返回的“响应”,但如果此post请求可能污染数据库中的数据,请利用Mock构建虚拟的post请求

)5)可用于演示

如果需要编写演示程序并创建简单的UI,则可以在完全没有开发后端服务的情况下进行演示。 说到演示,如果已经制作了系统,需要向客户进行演示,其中有些数据不想让用户看到,那么同样可以通过Mock界面替换所有这些敏感信息界面。

)6)测试覆盖度

如果有一个接口,有100种不同的返回,我们需要测试它在不同的返回下,系统是否能正常响应。 但是,有些返回在正常情况下几乎不会发生。 例如,如果接口发生500个错误,则需要测试APP是否崩溃。 别告诉我必须在服务器端代码上做手脚还500。 而且,用mock的话,这一切都会好的。 模拟你想要什么,你想要什么,什么会回来。 你不用再担心我的测试覆盖度了。

5、Mock测试存在的问题

虽然使用Mock测试可能会提高团队的开发效率,但是在b、c开发完代码后,需要将E2E测试代码从使用Mock测试更改为实际的模块调用,以避免模块之间集成部分漏测的问题这里mock存在的问题主要是避免/相信开发和测试过度依赖mock接口。

使用mock时,请不要忘记。

1 )测试人员不应该被高覆盖率的E2E自动化测试所迷惑,高覆盖率并不意味着没有问题。 特别是在交接新项目时,确认是否在E2E测试中使用Mock测试,进而确定在这些地方使用Mock测试是否合理,是否应该用实际的模块间调用和集成来替换这些Mock测试

2 )将mock连接器更换为实际的连接器后,测试/打开

发也必须把之前的测试重新做一遍。

ps: 俏皮的鲜花使用mock接口来提高效率,请注意:你的工作量其实是比 直接只用实际接口 多了 一倍的。如果测试时,偷懒,替换成实际接口后,只是简单测试,那么 当实际接口和mock预期接口有差异时,故障便和你相遇了。

建议: mock接口只能主流程联调/ 异常返回测试,不要过分依赖mock接口进行测试。

3)测试完毕,上线前,请一定确保 为了mock而做的相关代码/配置文件的修改,已经完全恢复了。

建议:上线checklist中条条列出,并上线前review

二、常用Mock框架

Mockito 和 PowerMock

Mockito是一个优秀的、最常用的单元测试mock框架,它能满足大部分时间的测试要求(public方法);

PowerMock可以去解决一些更难的问题(比如静态方法、私有方法、Final方法等)。

PowerMock 是在 EasyMock 以及 Mockito 基础上的扩展,通过提供定制的类加载器以及一些字节码篡改,实现更强大的测试功能。

三、Mockito的使用实例 1 . 测试类初始化

初始化方式有两种:

(1)注解

@RunWith(MockitoJUnitRunner.class) 换成@RunWith(PowerMockRunner.class)也可以支持这些注解。

@Mock相当于:NeedMockClass mockInstatnce = Mockito.mock(NeedMockClass.class); 还有一种@Spy后面提到,等价于NeedMockClass spyInstatnce = Mockito.spy(new NeedMockClass());

被测试类上标记@InjectMocks,Mockito就会实例化该类,并将标记@Mock、@Spy注解的属性值注入到被测试类中。

注意@InjectMocks的注入顺序:

  如果这里的TargetClass中没有显示定义构造方法,Mockito会调用默认构造函数实例化对象,然后依次寻找setter 方法 或 属性(按Mock对象的类型或名称匹配)注入@Mock对象;
   如果TargetClass中显式定义了有参数的构造函数,那么 就不再寻找setter 方法和 属性注入, Mockito会选择参数个数最多的构造函数实例化并注入@Mock对象(这样可以尽可能注入多的属性);

 但是有多个最大构造函数时,Mockito 究竟选择哪一个就混乱了,测试时应该避免这种情况的发生,很容易发生空指针。

(2)类反射

2. Mockito实例

测试类:@RunWith(MockitoJUnitRunner.class)public class MsgLogServiceTest { @InjectMocks private MsgLogService msgLogService; @Mock private MsgLogMapper msgLogMapper; @Mock private IZhwxApiService zhwxApiService; @Test public void handle_request_times_0_01() { Mockito.when(msgLogMapper.selectUnHandledMsg()).thenReturn(null); msgLogService.handle(); Mockito.verify(zhwxApiService, Mockito.times(0)).putProfileToHBase(Mockito.anyString()); Mockito.verify(msgLogMapper, Mockito.times(0)).updateHandleStatus(Mockito.any()); }} 注:when()、any()、verify()等都是Mockito类中的静态方法,推荐将这些静态方法导入,就可以在测试类中直接引用了import static org.mockito.Mockito.when;import static org.mockito.Mockito.verify;import static org.mockito.Matchers.any;

mock方法成立的一些条件

列举几个典型的匹配器:

any() : 任何参数

any(OrderInfo.class): 任何OrderInfo(开发中自定义的类)

anyString() :任何字符串,等同于any(String.class)

eq(1): 具体值1

List mockList = mock(List.class);when(mockList.get(5)).thenReturn("hello");//打桩Assert.assertEquals("hello", mockList.get(5));//打桩的情景返回设定值Assert.assertEquals(null, mockList.get(10));//未打桩的情景不会报错,返回默认值 断言 Assert.assertEquals() 

unit.framework包下的Assert提供了多个断言方法. 主用于比较测试传递进去的两个参数.

Assert.assertEquals();及其重载方法: 

1. 如果两者一致, 程序继续往下运行. 

2. 如果两者不一致, 中断测试方法, 抛出异常信息 AssertionFailedError 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。