EasyMock框架的使用详解

情景描述如下:

假设我们有一个BookService类,该类简单实现了借书和还书两个功能,但是BookService需要调用BookManager接口与数据库交互。

现在我们有一个尚未实现的接口BookManager(该借口主要用于数据库操作),假设现在我们没有数据库环境,那么我们就可以通过EasyMock框架来模拟实现其功能。

该情景下,使用EasyMock框架进行单元测试基本步骤如下:

1.调用cearteMock方法,来创建一个mock(模拟对象)来模拟BookManager接口

2.设定Mock对象的预期行为和输出

3.将Mock对象切换到Replay状态

4.调用Mock对象进行单元测试

5.对Mock对象的行为进行验证

注意事项:

1.先了解Mock Object的相关知识,再来使用EasyMock框架加深理解。

2.需要到EasyMock官网(http://easymock.org/)下载easymock的压缩包,然后把其中的easymock.jar包导入项目中。

(选中项目,右键选中构建路径,选择添加外部jar包,去找到对应的easymock.jar包位置即可)

具体代码示例如下:

//Book实体类

public class Book {
private String name;// 书名
private String isbn;//
private double price;// 价格
private boolean inShell; // 是否在架上

public Book() {
}

public Book(String name, String isbn, double price, boolean inShell) {
this.name = name;
this.isbn = isbn;
this.price = price;
this.inShell = inShell;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public String getISBN() {
return this.isbn;
}

public void setISBN(String isbn) {
this.isbn = isbn;
}

public double getPrice() {
return this.price;
}

public void setPrice(double price) {
this.price = price;
}

public boolean isInShell() {
return this.inShell;
}

public void setInShell(boolean inShell) {
this.inShell = inShell;
}

}

//BookManager接口,用于和数据库交互

public interface BookManager {

Book findBook(String isbn); // 根据isbn在数据库中找到相应的书籍

void updateBook(Book book); // 更新数据库中书籍的状态(是否在书架上)

}

//BookService类,简单实现借书,还书两个功能

public class BookService {
private BookManager bookManager;

public BookService(BookManager bookManager) {
this.bookManager = bookManager;
}

/**
* 借书
*
* @param isbn
* @return
*/
public boolean borrowBook(String isbn) {
Book book = bookManager.findBook(isbn);
if (book != null && book.isInShell()) {
// 书籍存在并且在书架上
book.setInShell(false);
bookManager.updateBook(book);
return true;
}
return false;
}

/**
* 还书
*
* @param isbn
* @return
*/
public boolean returnBook(String isbn) {
Book book = bookManager.findBook(isbn);
if (book != null && !book.isInShell()) {
// 书籍存在且不在书架上
book.setInShell(true);
return true;
}
return false;
}

}

//使用EasyMock框架进行模拟测试

import static org.junit.Assert.*;

import static org.easymock.EasyMock.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestBookServiceEasyMock {

// 声明我们想要mock的对象
// 核心EasyMock框架只能mock接口对象
private BookManager mockBookManager = null;
private Book book1 = null;
private Book book2 = null;

@Before
public void setUp() throws Exception {
// 调用 createMock方法,来创建一个mock来模拟BookManager
mockBookManager = createMock("mockBookManager", BookManager.class);
// 创建两本书
book1 = new Book("软件测试自动化", "1", 32.3, true);
book2 = new Book("软件测试过程管理", "2", 35.3, false);
}

@After
public void tearDown() throws Exception {

// 验证Mock对象行为
verify(mockBookManager);
}

// 正常借书
@Test
public void testBorrowBook1() {

// 使用EasyMock我们有两种声明预期的方法
// 当方法的返回值类型为void,我们就在mock object上调用此方法
// 当方法返回任何类型的对象,我们需要使用EasyMock API中的expect和andReturn方法

expect(mockBookManager.findBook("1")).andReturn(book1);
mockBookManager.updateBook(book1);

// 需要调用 replay方法来切换Mock对象的状态
replay(mockBookManager);

BookService bookService = new BookService(mockBookManager);
boolean flag = bookService.borrowBook("1");
assertTrue(flag);
assertFalse(book1.isInShell());

}

// 所借书籍不存在
@Test
public void testBorrowBook2() {

expect(mockBookManager.findBook("3")).andReturn(null);
// 需要调用 replay方法来切换Mock对象的状态

replay(mockBookManager);

BookService bookService = new BookService(mockBookManager);
boolean flag = bookService.borrowBook("3");
assertFalse(flag);

}

// 所借书籍不在书架上
@Test
public void testBorrowBook3() {

expect(mockBookManager.findBook("2")).andReturn(book2);

// 需要调用 replay方法来切换Mock对象的状态
replay(mockBookManager);

BookService bookService = new BookService(mockBookManager);
boolean flag = bookService.borrowBook("2");
assertFalse(flag);
assertFalse(book2.isInShell());
}

// 正常还书
@Test
public void testReturnBook1() {

expect(mockBookManager.findBook("2")).andReturn(book2);

// 需要调用 replay方法来切换Mock对象的状态
replay(mockBookManager);

BookService bookService = new BookService(mockBookManager);
boolean flag = bookService.returnBook("2");
assertTrue(flag);
assertTrue(book2.isInShell());
}

// 所还书籍不存在
@Test
public void testReturnBook2() {

expect(mockBookManager.findBook("3")).andReturn(null);

// 需要调用 replay方法来切换Mock对象的状态
replay(mockBookManager);

BookService bookService = new BookService(mockBookManager);
boolean flag = bookService.returnBook("3");
assertFalse(flag);

}

// 所还书籍已在书架上
@Test
public void testReturnBook3() {

expect(mockBookManager.findBook("1")).andReturn(book1);

// 需要调用 replay方法来切换Mock对象的状态
replay(mockBookManager);

BookService bookService = new BookService(mockBookManager);
boolean flag = bookService.returnBook("1");
assertFalse(flag);
assertTrue(book1.isInShell());
}

}

时间: 2024-10-10 09:43:03

EasyMock框架的使用详解的相关文章

Spring MVC 框架搭建及详解

一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.commons-logging.jar.cglib-nodep-2.1_3.jar Hibernate 3.6.8:hibernate3.jar.hibernate-jpa-2.0-api-1.0.1.Final.jar.antlr-2.7.6.jar.commons-collections-3

SSH框架--struts深入详解(一)

学习了struts,但是对于它的由来,以及为什么使用action和struts.xml的方式而不采用以前的servlet方式,有些疑问,到底之前的方式有什么弊端,struts又给我们带来了什么便利? 下面一一为大家解答! struts的由来: 随着JSP与Servlet 技术大量应用于以Web为基础的应用程序,为了提升Web 应用程序可维护性与重复使用性,Java开发人员提出了一些较佳的开发模式.比较常见的两种JSP应用架构分别为Model1 与Model 2.详情参见(JAVA学习篇--JAV

SSH框架的整合详解

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> SSH框架的整合详解 - super_YC的博客 - 博客频道 - CSDN.NET super_YC的博客 记录我生活的一点一滴!我很开心拥有这样一个自己心事的笔记本 目录视图 摘要视图 订阅 [活动]2017 CSDN博客专栏评选 &nbsp [5月书讯]流畅的P

java的集合框架最全详解

java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作的方法. 在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework). Java程序员在具体应用时,不必考虑数据结构和算法实现细节,只需要用这

Java的集合框架最全详解(图)

纯个人整理,如有错误请指正. java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作的方法. 在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework). Java程序员在具体应用时,不必考虑数据

spring框架 AOP核心详解

AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Aspect(切面):通常是一个类,里面可以定义切入点和通知 (2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用 (3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around

Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)

最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发.在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所帮助. 首先按照惯例先来简单了解一些AsyncHttpClient网络框架的一些知识. 1.简介 Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnect,但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求,而使用android-a

Java并发---- Executor并发框架--ThreadToolExecutor类详解(execute方法)

1.构造方法 请参考上篇文章:http://blog.csdn.net/ochangwen/article/details/53044733 2.源码详解 线程池内部有一些状态,先来了解下这些状态的机制.以下用代码注释的方式来解释其中的含义. /* 这个是用一个int来表示workerCount和runState的,其中runState占int的高3位, 其它29位为workerCount的值. workerCount:当前活动的线程数: runState:线程池的当前状态. 用AtomicIn

Struts2.0 框架搭建步骤详解

实现了MVC思想的struts框架,主要分三层结构,即:view->controller->model,三者互相传递数据,实现了数据在前台和后台的转换,验证,展示,存储. 搭建struts框架的步骤如下: 1.在myeclipse中新建Java项目,删除项目中的源文件src,建立普通文件,将Struts解压后的jar包复制在新建的普通文件夹中. 2.新建web项目,右键选择build path->add jars(不是导入外部第三方的jar包) 选择第一步新建的Java项目,将里面的Ja