`

Mockito(三)--完整功能介绍

阅读更多

        mockito官网:http://code.google.com/p/mockito/,打开documentation可以看到官方最新的文档资料。

一.使用mockito验证行为

//首先要import Mockito
import static org.mockito.Mockito.*;

//mock creation
List mockedList = mock(List.class);

//using mock object
mockedList.add("one");
mockedList.clear();

//验证add方法是否在前面被调用了一次,且参数为“one”。clear方法同样。
verify(mockedList).add("one");
verify(mockedList).clear();

//下面的验证会失败。因为没有调用过add("two")。
verify(mockedList).add("two");

        原文中的一句话很重要:Once created, mock will remember all interactions.所以mockito知道前面是否调用过某方法。

 

二.使方法调用返回期望的值,也被称为stubbing

//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);

//stubbing。当get(0)被调用时,返回"first". 方法get(1)被调用时,抛异常。
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());

//following prints "first"
System.out.println(mockedList.get(0));

//following throws runtime exception
System.out.println(mockedList.get(1));

//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));

        默认情况下,对于所有有返回值且没有stub过的方法,mockito会返回相应的默认值。对于内置类型会返回默认值,如int会返回0,布尔值返回false。对于其他type会返回null。

        这里一个重要概念就是: mock对象会覆盖整个被mock的对象,因此没有stub的方法只能返回默认值。

//重复stub两次,则以第二次为准。如下将返回"second":
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(0)).thenReturn("second");

//如果是下面这种形式,则表示第一次调用时返回“first”,第二次调用时返回“second”,可以写n多个
when(mockedList.get(0)).thenReturn("first").thenReturn("second");

        注意:如果实际调用的次数超过了stub过的次数,则会一直返回最后一次stub的值。如上例,第三次调用get(0)时,则会返回"second"。

 

三.参数匹配

        在上例中如果想实现get(任意整数)时,都返回“element”时,该怎么做呢?很简单。

//stubbing 使用了内置的anyint() matcher.
when(mockedList.get(anyInt())).thenReturn("element");

//因此除了anyint()之外,还有其他很多matcher。这里请参考原文。
//使用了matcher一样可以验证被调用的次数。
verify(mockedList).get(anyInt());

        这里有一个限制就是,如果在调用方法时需要传入多个参数,其中一个参数使用了argument matcher,那么所有的参数必须都是matcher,不可以matcher和实际的参数混着用。

        这里也可以使用custom argument matcher。因为很多时候输入参数不是build-in 类型,而是我们自己写的一些类,或特殊对象,这时要使用argument matcher,就必须订制特殊的matcher了。

        下例是一个特殊的matcher的实例,这个matcher可以匹配任何file对象。

public class SayHiTest {

    @Test
    public void testSayHi() throws Exception {
        
        //首先mock File类
        File mock = mock(File.class);
        
        //注意new IsAnyFiles()并不是一个matcher,需要调用argThat(new IsAnyFiles()))才返回一个matcher。
        //下句中stub:当调用renameTo方法时,返回false。该方法参数可以是任意file对象。
        when(mock.renameTo(argThat(new IsAnyFiles()))).thenReturn(false);
        mock.renameTo(new File("test"));

        //下句verify renameTo方法被调用了一次,同时输入参数是任意file。
        verify(mock).renameTo(argThat(new IsAnyFiles()));
    }
}

class IsAnyFiles extends ArgumentMatcher<File> {
    public boolean matches(Object file) {
        return file.getClass() == File.class;
    }
}

 另外一个参数匹配的例子:

class IsSOAPMessage extends ArgumentMatcher<SOAPMessage> {
    //这里的macther不仅可以匹配任意的SOAPMessage对象,如果输入参数为空也可以匹配上。
    public boolean matches(Object soapMessage) {
        return (soapMessage instanceof SOAPMessage) || soapMessage==null;
    }
}

        做参数匹配的时候,需考虑到输入参数为空的情况,因为如果为空,会导致matcher匹配不上,进而stub的行为无法生效。

        发现mock对象没有想自己想象的方式工作时,最好的方法就是debug进去,首先要先确定mock对象是不是真的传递进去了,然后再一步步的debug。通常遇到的两种情况就是:1.mock对象没有传递进去;2.参数没有匹配上。

 

四.验证方法被调用了特定次数/至少x次/最多x次/从未被调用

//是否add("twice")被调用了两次。
verify(mockedList, times(2)).add("twice");

//验证add("twice")被调用了至少一次。以及其他。
verify(mockedList, atLeastOnce()).add("twice");
verify(mockedList, atLeast(2)).add("twice");
verify(mockedList, atMost(5)).add("twice");
verify(mockedList, never()).add("twice");

 

五.调用方法时抛出异常

doThrow(new RuntimeException()).when(mockedList).clear();

 

六.验证顺序

//下面的代码验证firstMock先被调用,secondMock后被调用。
inOrder.verify(firstMock).add("was called first");
inOrder.verify(secondMock).add("was called second");

 

七.验证mock之间没有相互作用

 

八.找到冗余的调用

        用never()就可以实现,不多说。

 

九.使用@mock 定义mock

        之前都是使用mock()来模拟一个对象,用@mock是一个shorthand。

public class ArticleManagerTest {

    @Mock
    private ArticleCalculator calculator;

    @Mock
    private ArticleDatabase database;

    @Mock
    private UserProvider userProvider;

    private ArticleManager manager;
}
分享到:
评论

相关推荐

    Mockito Cookbook - Packt

    - **主要功能**:本书提供了大量的实例来展示Mockito功能的实际应用,不仅限于文档介绍,还包括如何高效地使用Mockito进行单元测试的方法。 - **应用场景**:适用于JUnit、PowerMock、TestNG等流行单元测试框架。 #...

    Practical-Unit-Testing-with-TestNG-and-Mockito_examples

    TestNG和Mockito是两个非常流行的Java单元测试工具,它们提供了强大的功能和灵活的用法。本篇将深入探讨这两者的应用,并结合具体实例进行详细解析。 一、TestNG简介 TestNG是由Cédric Beust创建的一个自动化测试...

    Android-Test-With-JUnit-Mockito-RoboElectric

    本项目"Android-Test-With-JUnit-Mockito-RoboElectric"主要关注的是使用JUnit、Mockito和Robolectric这三款强大的工具来实现Android应用的单元测试和模拟测试。以下将详细介绍这些工具以及它们在Android测试中的...

    Packt Publishing Mockito Essentials (2014)

    #### 三、加速Mockito - **高级Mockito特性**: - **处理void方法**:通过`doNothing()`、`doReturn()`等方法来模拟void方法的行为。 - **从void方法抛出异常**:可以在模拟的void方法上调用`doThrow()`来抛出...

    Practical Unit Testing with TestNG and Mockito

    虽然这里只介绍了基础的内容,但在实践中不断深入探索这些工具的功能和技术细节将极大地提高软件开发的质量和效率。希望每位开发者都能够重视并充分利用单元测试的力量,让自己的代码更加健壮和可靠。

    Mastering Unit Testing Using Mockito and JUnit

    - **Spying on Real Objects**:如果需要部分模拟某个真实对象,可以使用Mockito的spy功能。 #### 四、JUnit与Mockito的结合使用 结合使用JUnit和Mockito可以让测试更加灵活和强大。 - **Setup**:首先需要设置...

    mockito单元测试

    #### 三、Mockito 的基本用法 ##### 3.1 创建Mock对象 Mockito提供了一个简单易用的API来创建Mock对象。可以通过以下几种方式创建Mock对象: ```java // 创建一个未命名的Mock对象 List mockedList = mock(List....

    Mockit资料,自用

    以上只是Mockito的基本介绍,实际使用中还涉及到更多高级特性和技巧,通过学习提供的Mockit资料,你可以更深入地掌握Mockito,提高测试的质量和效率。记住,良好的测试是软件质量的保障,Mockito就是实现这一目标的...

    基于Springboot+Junit+Mockito做单元测试的示例

    Mockito是一个流行的Mocking框架,提供了mock对象的功能,可以用来模拟外部依赖项,例如数据库、Redis、外部服务等。 五、隔离外部依赖 在单元测试中,需要隔离外部依赖项,以避免外部依赖项的影响。Mockito可以...

    基于开源项目RuoYi-Vue,扩展开发添加新业务功能。基于SpringBoot,Spring Security,J.zip

    1. **单元测试**:使用JUnit和Mockito等工具对新业务功能进行单元测试,确保功能正常无误。 2. **集成测试**:检查新功能与现有系统间的交互,确保整体流程的顺畅。 3. **部署上线**:打包应用,配置服务器环境,将...

    Android代码-医院介绍电子书籍源码.zip

    《Android代码-医院介绍电子书籍源码》是一个用于创建医院介绍类电子书籍的应用程序源代码。这个项目基于Android平台,提供了详细的实现方案,为开发者展示了如何利用Android SDK开发一款功能丰富的移动应用。以下是...

    springboot图书电子商务网站的设计与实现-java-文档-论文-springboot图书电子商务网站的设计与实现文档

    - 使用JUnit和Mockito进行单元测试,确保每个模块的功能正确性。 - 对关键业务逻辑进行覆盖率测试,提高代码质量。 #### 4.2 集成测试 - 在模拟环境中对整个系统进行集成测试,验证各个模块之间的协同工作能力。 - ...

    java实现仿百度文库功能完整代码

    下面将详细介绍这个项目的实现原理、关键技术以及涉及的Java知识点。 1. **PDF处理** - Java中的PDF处理库:在Java中,我们可以使用如Apache PDFBox、iText或 Flying Saucer 这样的库来解析、操作和展示PDF文件。...

    毕业设计-基于Java的第三方考研机构信息管理系统.zip

    本系统的核心功能包括但不限于用户管理、课程信息发布、报名管理、成绩管理以及数据分析等多个模块,为考研学生与第三方教育机构之间的信息交互提供了便利。 首先,系统采用了Java作为主要开发语言,这是因为Java...

    使用模仿对象进行测试nmock

    一、nMock 框架介绍 nMock 是一款开源的 .NET 模拟对象库,它提供了动态接口模仿和行为验证的功能。nMock 提供了一种声明式的 API 来定义模仿对象的行为,可以用于模拟方法调用、设置期望和验证方法的执行情况。 二...

    使用Android Studio进行本地单元测试

    这些依赖库主要用于支持单元测试框架的功能,如Mockito和Hamcrest等。 ##### 3.1 修改依赖库源 根据给定的部分内容,需要将项目的`build.gradle`文件中的依赖源从“jcenter()”修改为: ```groovy // 修改依赖源 ...

    Java柠檬班Java全栈自动化-视频课程资源网盘链接提取码下载 .txt

    - **Spring Boot框架**:详细介绍Spring Boot框架的核心功能,如依赖注入、自动配置等,并通过实战项目演示其应用。 - **数据库操作**:教授SQL语言基础及高级查询技巧;使用ORM框架如MyBatis或Hibernate进行数据库...

    springboot全套学习资料.txt

    - **Mockito**:介绍如何使用Mockito模拟对象的方法。 #### 二、Spring Boot高级篇 ##### 2.1 配置文件 - **YAML与Properties**:介绍Spring Boot支持的两种配置文件格式及其优缺点。 - **外部配置**:介绍如何...

    登录与注册界面的实现,同时实现前后端的交互功能

    下面将详细介绍这个过程。 **一、Spring框架** Spring是一个开源的应用框架,它提供了丰富的功能,包括依赖注入、面向切面编程、事务管理等。在这个项目中,Spring主要负责管理对象的生命周期和依赖关系,使我们能...

    毕设项目:基于springboot的食堂管理系统.zip

    【描述】中提到,这个项目是免费提供的,适用于毕业生进行毕业设计或课程设计,意味着它可能包含了完整的功能模块和基础架构,便于学生快速理解和实现一个实际的系统。源码已经过测试,可以直接运行,这意味着初学者...

Global site tag (gtag.js) - Google Analytics