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());
}

}

posted @ 2015-04-23 10:46  丶小八戒  阅读(877)  评论(0编辑  收藏  举报