【翻译】Java使用Mockito进行Mock测试

我们所有人在编写单元测试的时候面临的巨大挑战是模块对其他组件的依赖。同时花费大量的时间和精力去配置依赖的组件环境是一件出力不讨好的事情。使用Mock是一种有效地方式替代其他组件用来继续我们的单元测试构建过程。

接下来我将会展示一个使用mock技术的实例。这里我有一个数据访问层(简称DAL),建立一个类,提供应用程序访问和修改数据库中数据的基本API。接着我会测试这个DAL实例,但并不真正连接数据库。使用DAL类的目的是帮助我们隔离应用程序代码和数据显示层。

让我们通过下面的命令行创建一个java maven 项目。



mvn archetype:generate -DgroupId=info.sanaulla -DartifactId=MockitoDemo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

上述命令会创建一个名为MockitoDemo 的文件夹以及对应实体类的目录结构和测试文件。

请参考下面的例子来创建一个实体类:



package info.sanaulla.models;

import java.util.List;

/**


  • Model class for the book details. */ public class Book { private String isbn; private String title; private List authors; private String publication; private Integer yearOfPublication; private Integer numberOfPages; private String image; public Book(String isbn,
          String title,
          List<String> authors,
          String publication,
          Integer yearOfPublication,
          Integer numberOfPages,
          String image){
    

    this.isbn = isbn;

    this.title = title;

    this.authors = authors;

    this.publication = publication;

    this.yearOfPublication = yearOfPublication;

    this.numberOfPages = numberOfPages;

    this.image = image;

    }

    public String getIsbn() {

    return isbn;

    }

    public String getTitle() {

    return title;

    }

    public List getAuthors() {

    return authors;

    }

    public String getPublication() {

    return publication;

    }

    public Integer getYearOfPublication() {

    return yearOfPublication;

    }

    public Integer getNumberOfPages() {

    return numberOfPages;

    }

    public String getImage() {

    return image;

    }

    }

用来操作Book类的DAL类如下:



package info.sanaulla.dal;

import info.sanaulla.models.Book;

import java.util.ArrayList; 

import java.util.Arrays; 

import java.util.Collections; 

import java.util.List;

/**


  • API layer for persisting and retrieving the Book objects. */ public class BookDAL { private static BookDAL bookDAL = new BookDAL(); public List getAllBooks(){ return Collections.EMPTY_LIST; } public Book getBook(String isbn){ return null; } public String addBook(Book book){ return book.getIsbn(); } public String updateBook(Book book){ return book.getIsbn(); } public static BookDAL getInstance(){ return bookDAL; } }

DAL 层现在并没有实际的功能,我将尝试用测试驱动开发的方式来构建(TDD)。我们并不关心,DAL层是通过实体关系映射来进行数据通信还是通过其他数据库API来实现上面的操作。

数据驱动的数据访问层

有很多单元测试框架和mock框架,这里我选择Junit单元测试框架和moke框架Mockito。我们需要在pom.xml配置文件中更新对他们的依赖。

   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 <a href="http://maven.apache.org/maven-v4_0_0.xsd">http://maven.apache.org/maven-v4_0_0.xsd"</a>>
  <modelVersion>4.0.0</modelVersion>
  <groupId>info.sanaulla</groupId>
  <artifactId>MockitoDemo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>MockitoDemo</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- Dependency for JUnit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    <!-- Dependency for Mockito -->
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.9.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

现在我们编写BookDAL的单元测试类。通过单元测试,我们可以在BookDAL中注入mock对象进行单元测试而不用依赖其他数据源。

首先建立一个空的测试类,代码如下:



public class BookDALTest {

public void setUp() throws Exception {

}

public void testGetAllBooks() throws Exception {

}

public void testGetBook() throws Exception {

}

public void testAddBook() throws Exception {

}

public void testUpdateBook() throws Exception {



} 

} 


下面的代码中,我们在setUp方法中通过mock方式注入BookDAL对象



public class BookDALTest {

private static BookDAL mockedBookDAL; 

private static Book book1; 

private static Book book2;

@BeforeClass 

public static void setUp(){
//Create mock object of BookDAL
mockedBookDAL = mock(BookDAL.class);

//Create few instances of Book class.
book1 = new Book("8131721019","Compilers Principles",
        Arrays.asList("D. Jeffrey Ulman","Ravi Sethi", "Alfred V. Aho", "Monica S. Lam"),
        "Pearson Education Singapore Pte Ltd", 2008,1009,"BOOK_IMAGE");

book2 = new Book("9788183331630","Let Us C 13th Edition",
        Arrays.asList("Yashavant Kanetkar"),"BPB PUBLICATIONS", 2012,675,"BOOK_IMAGE");

//Stubbing the methods of mocked BookDAL with mocked data.
when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2));
when(mockedBookDAL.getBook("8131721019")).thenReturn(book1);
when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn());
when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn());

}

public void testGetAllBooks() throws Exception {}

public void testGetBook() throws Exception {}

public void testAddBook() throws Exception {}

public void testUpdateBook() throws Exception {}

}

在setUp方法中我通过下面这种方式

1.创建BookDAL实例:



BookDAL mockedBookDAL = mock(BookDAL.class);

2.Mokito API中DAL的mock对象,使用when方法接收调用mock对象的方法返回值参数。



//When getAllBooks() is invoked then return the given data and so on for the other methods.

when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2));

when(mockedBookDAL.getBook(“8131721019”)).thenReturn(book1);

when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn());

when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn());

实现其他的已经声明的测试方法:



package info.sanaulla.dal;

import info.sanaulla.models.Book; 

import org.junit.BeforeClass; 

import org.junit.Test;

import static org.junit.Assert.*; 

import static org.mockito.Mockito.mock; 

import static org.mockito.Mockito.when;

import java.util.Arrays; 

import java.util.List;

public class BookDALTest {

private static BookDAL mockedBookDAL; 

private static Book book1; 

private static Book book2;

@BeforeClass 

public static void setUp(){
mockedBookDAL = mock(BookDAL.class);
book1 = new Book("8131721019","Compilers Principles",
        Arrays.asList("D. Jeffrey Ulman","Ravi Sethi", "Alfred V. Aho", "Monica S. Lam"),
        "Pearson Education Singapore Pte Ltd", 2008,1009,"BOOK_IMAGE");

book2 = new Book("9788183331630","Let Us C 13th Edition",
        Arrays.asList("Yashavant Kanetkar"),"BPB PUBLICATIONS", 2012,675,"BOOK_IMAGE");

when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2));
when(mockedBookDAL.getBook("8131721019")).thenReturn(book1);
when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn());

when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn());

}

@Test

public void testGetAllBooks() throws Exception {

List<Book> allBooks = mockedBookDAL.getAllBooks();
assertEquals(2, allBooks.size());
Book myBook = allBooks.get(0);
assertEquals("8131721019", myBook.getIsbn());
assertEquals("Compilers Principles", myBook.getTitle());
assertEquals(4, myBook.getAuthors().size());
assertEquals((Integer)2008, myBook.getYearOfPublication());
assertEquals((Integer) 1009, myBook.getNumberOfPages());
assertEquals("Pearson Education Singapore Pte Ltd", myBook.getPublication());
assertEquals("BOOK_IMAGE", myBook.getImage());

}

@Test

public void testGetBook(){

String isbn = "8131721019";
Book myBook = mockedBookDAL.getBook(isbn);

assertNotNull(myBook);
assertEquals(isbn, myBook.getIsbn());
assertEquals("Compilers Principles", myBook.getTitle());
assertEquals(4, myBook.getAuthors().size());
assertEquals("Pearson Education Singapore Pte Ltd", myBook.getPublication());
assertEquals((Integer)2008, myBook.getYearOfPublication());
assertEquals((Integer)1009, myBook.getNumberOfPages());

}

@Test

public void testAddBook(){

String isbn = mockedBookDAL.addBook(book1);
assertNotNull(isbn);
assertEquals(book1.getIsbn(), isbn);

}

@Test

public void testUpdateBook(){

String isbn = mockedBookDAL.updateBook(book1);
assertNotNull(isbn);
assertEquals(book1.getIsbn(), isbn);

}

}

然后我们通过maven的命令航方式:mvn test运行当前的项目。控制台输出如下:



-——————————————————

T E S T S

-——————————————————

Running info.sanaulla.AppTest

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 sec

Running info.sanaulla.dal.BookDALTest

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.209 sec

Results :



Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 


现在我们就实现了即使不配置数据源方式,而使用mock对象来测试DAL类。

实例代码

网盘地址:MockitoDemo

时间: 2024-10-14 08:35:42

【翻译】Java使用Mockito进行Mock测试的相关文章

mock测试框架Mockito

无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访问实际的文件系统或数据库),而TDD经常会碰到协同模块尚未开发的情况,而mock技术正是解决这些问题的灵丹妙药. mock技术的目的和作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开. 我们可以自己编写自定义的Mock对象实现mock技术,但是编写自定义的Mo

Mock测试框架(Mockito为例)

在做单元测试的时候,有的时候用到的一些类,我们构造起来不是那么容易,比如HttpRequest,或者说某个Service依赖到了某个Dao,想构造service还得先构造dao,这些外部对象构造起来比较麻烦. 所以出现了Mock! 我们可以用 Mock 工具来模拟这些外部对象,来完成我们的单元测试. 实现Mock技术的优秀开源框架有很多,下面以Mockito为例,用几个简单例子来介绍Mock工具的基本使用: 1.Mockito的第一个示例 1 @Test 2 public void simple

java的mock测试框架

无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访问实际的文件系统或数据库),而TDD经常会碰到协同模块尚未开发的情况,而mock技术正是解决这些问题的灵丹妙药. mock技术的目的和作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开. 我们可以自己编写自定义的Mock对象实现mock技术,但是编写自定义的Mo

简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)

本文将简单介绍如何使用PowerMock和Mockito来mock1. 构造函数2. 静态函数3. 枚举实现的单例4. 选择参数值做为函数的返回值5. 在调用mock出来的方法中,改变方法参数的值 一点简要说明:Mockito其实已经可以满足大部分的需求,但是它的实现机制是使用cglib来动态创建接口的类的实例.但是这种实现方式不能用于构造函数和静态函数,因为那需要使用类的字节码(比如使用javassist). 所以我们才需要结合使用PowerMock. 1. mock构造函数, 如果有代码没有

mock测试到底是什么?

?    ?经常听人说mock测试,究竟什么是mock测试呢?mock测试能解决什么问题?mock测试要如何做呢?今天为大家做简单介绍,之后会有详细的mock测试,感谢大家对测试梦工厂的持续关注. 概念 ?    ?mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法. MockObject ?    ?使用Mock Object进行测试,主要是用来模拟那些在应用中不容易构造(如HttpServletRequest必须在Servlet容器

使用PowerMock进行Mock测试

安装 下载地址:https://github.com/jayway/powermock/wiki/Downloads.下载" Mockito and JUnit including dependencies"版本.当前版本为”powermock-mockito-junit-1.6.3.zip". IntelliJ IDEA的设置如下: 右击工程,选择“Open Module Settings” 按下“ALT + Insert”,选择“Jars or directories..

Spring自带mock测试Controller

转自:http://blog.csdn.net/yin_jw/article/details/24726941 分类: Spring开源框架2014-04-29 17:01 1786人阅读 评论(2) 收藏 举报 Spring自带mock测试Contro 准备SpringMVC环境 注意:使用mock测试需要引入spring-test包 Base类:加载配置文件 [java] view plaincopy package com.wyy.snail.user.controller; import

使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等

依赖:这个很重要,不同版本用法也有点区别: <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>2.0.2-beta</version> <scope>test</scope> </dependency> <dependency> <group

小程聊微服务-基于dubbo的mock测试系统

一.说在前面 基于微服务或者SOA的自动化测试系统每个公司都有自己的特有的,我今天就主要介绍一下,我们研发的一套mock测试系统. 二.目前面临的问题 1.测试人员面临的测试问题 我公司目前用的是基于Dubbo的微服务改造,服务之间的调用链路冗长,每个服务又是单独的团队在维护,每个团队又在不断的演进和维护各个服务,那么对测试人员将是非常大的挑战. 测试人员每次进行功能测试的时候,测试用例每次都需要重新写一遍,无法将测试用例的数据沉淀,尤其是做自动化测试的时候,测试人员准备测试数据就需要很长时间,