zoukankan      html  css  js  c++  java
  • 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());
    }

    }

  • 相关阅读:
    绿色通道
    Banknotes
    旅行问题
    修剪草坪
    最大连续和
    动物园
    炮兵阵地
    涂抹果酱
    牧场的安排
    国王
  • 原文地址:https://www.cnblogs.com/houxi/p/4449704.html
Copyright © 2011-2022 走看看