Mock测试详细介绍及使用

最近在写一个微服务的项目,项目中使用了Mock。Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开。

定义

1.什么是Mock
mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mock对象来模拟对象的行为。比如说你需要调用B服务,可是B服务还没有开发完成,那么你就可以将调用B服务的那部分给Mock掉,并编写你想要的返回结果。

2.Spring Boot的测试类库
现在绝大多数的java服务都是Spring框架搭建的,并且也会使用到Spring boot来进行快速搭建开发,在Spring Boot提供了许多实用工具和注解来帮助测试应用程序,主要包括以下两个模块:

  • spring-boot-test:支持测试的核心内容。
  • spring-boot-test-autoconfigure:支持测试的自动化配置。

开发进行只要使用 spring-boot-starter-test 启动器就能引入这些 Spring Boot 测试模块,还能引入一些像 JUnit, AssertJ, Hamcrest 及其他一些有用的类库。

3.Mockito工具
Mockito 是 Java 单元测试 Mock 框架,开源。

大多 Java Mock 库如 EasyMock 或 JMock 都是 expect-run-verify (期望-运行-验证)方式,而 Mockito 则使用更简单,更直观的方法:在执行后的互动中提问。使用 Mockito,你可以验证任何你想要的。而那些使用 expect-run-verify 方式的库,你常常被迫查看无关的交互。

非 expect-run-verify 方式 也意味着,Mockito 无需准备昂贵的前期启动。他们的目标是让开发人员专注于测试选定的行为。

Mockito 拥有的非常少的 API,所有开始使用 Mockito,几乎没有时间成本。因为只有一种创造 mock 的方式。只要记住,在执行前 stub,而后在交互中验证。你很快就会发现这样的TDD java 代码是多么自然。

类似 EasyMock 的语法来的,所以你可以放心地重构。Mockito 并不需要“expectation(期望)”的概念。只有 stub 和verify。

Mockito 实现了 Gerard Meszaros 所谓的 Test Spy.

项目中,有些函数需要处理某个服务的返回结果,而在对函数单元测试的时候,又不能启动那些服务,这里就可以利用Mockito工具,其中有如下三种注解:

  • @InjectMocks:创建一个实例,简单的说是这个Mock可以调用真实代码的方法,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。

  • @Mock:对函数的调用均执行mock(即虚假函数),不执行真正部分。

  • @Spy:对函数的调用均执行真正部分。

Mock 与 Stub 的区别

Mock 不是 Stub,两者是有区别的:

前者被称为 mockist TDD,而后者一般称为 classic TDD ;
前者是基于行为的验证(behavior verification),后者是基于状态的验证 (state verification);
前者使用的是模拟的对象,而后者使用的是真实的对象。

所谓打桩Stub,就是用来提供测试时所需要的测试数据,因为是mock的对象,所以可能有些方法并不能知道返回值,因此我们需要去假定返回值。可以对各种交互设置相应的回应,即对方法设置调用返回值,使用when(…).thenReturn(…)。

4. 常用的 Mockito 方法:
Mockito的使用,一般有以下几种组合:

  • do/when:包括doThrow(…).when(…)/doReturn(…).when(…)/doAnswer(…).when(…)

  • given/will:包括
    given(…).willReturn(…)/given(…).willAnswer(…)
    例如:given(userRepository.findByUserName(Mockito.anyString())).willReturn(user);
    given用于对指定方法进行返回值的定制,它需要与will开头的方法一起使用
    通过willReturn可以直接指定打桩的方法的返回值

  • when/then: 包括when(…).thenReturn(…)/when(…).thenAnswer(…)
    例如:when(userRepository.findByUserName(Mockito.anyString())).thenReturn(user);
    when的作用与Given有点类似,但它一般与then开头的方法一起使用。
    thenReturn与willReturn类似,不过它一般与when一起使用。

具体应用

以下一个具体例子:

/**
  * If an item is loaded from the repository, the name of that item should 
  * be transformed into uppercase.
  */
@Test
public void shouldReturnItemNameInUpperCase() {
   
 
    //
    // Given
    //
    Item mockedItem = new Item("it1", "Item 1", "This is item 1", 2000, true);
    when(itemRepository.findById("it1")).thenReturn(mockedItem);
 
    //
    // When
    //
    
  • 3
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值