现在的位置: 首页 > 综合 > 正文

使用EasyMock进行单元测试

2018年05月09日 ⁄ 综合 ⁄ 共 4258字 ⁄ 字号 评论关闭

 

 

1.      


单元测试就是对软件的一个单元进行隔离测试,然而大多数软件的各个单元并不是孤立,它们相互协作,有着千丝万缕的联系,因此为了对一个单元进行测试,我们就必须对这个单元依赖的其他单元进行模拟。
EasyMock
是第一个动态模拟对象生成器,它将程序员从手工编写模拟对象的繁琐中解脱出来。在进行测试之前,先要下载easyMock的包并且加载到库中


 

2. 编写工资计算方法的接口
ISalaryCalculator

 

package org.liky.junit.easymock;

public interface ISalaryCalculator {
    public double calculate(Position position);

}

 

3.编写职位枚举Position

 

package org.liky.junit.easymock;

public enum Position {
BOSS, MANAGER, PROGRAMMER

}


4. 编写工资计算方法
ISalaryCalculator的实现类

 

package org.liky.junit.easymock;

public class SalaryCalculator implements ISalaryCalculator {

public double calculate(Position position) {
      double salary = 0;

        switch (position) {
        case BOSS:
            salary = 10000;
            break;
        case MANAGER:
            salary = 8000;
            break;
        case PROGRAMMER:
            salary = 6000;
            break;
        default:
            throw new RuntimeException("No position for employee!");
        }
        return salary;
    }
}

 

5.编写工资计算的类
IncomeCalculator

 

package org.liky.junit.easymock;

public class IncomeCalculator {

    private ISalaryCalculator salaryCalculator;
    private Position position;

    public void setSalaryCalculator(ISalaryCalculator salaryCalculator) {
        this.salaryCalculator = salaryCalculator;
    }

    public void setPosition(Position position) {
        this.position = position;
    }
   
    public double calculate() {
        if (salaryCalculator == null) {
            throw new SalaryCalculatorException("Sorry, Salary Calculator is null!");
        }
        if (position == null) {
            throw new PositionException("Sorry, Salary Calculator is null!");
        }
        return salaryCalculator.calculate(position);
    }

}

 

6. 自定义异常
RuntimeException

 

package org.liky.junit.easymock;

public class PositionException extends RuntimeException {

    private static final long serialVersionUID = -4344038596220235806L;
   
    public PositionException() {
        super();
    }
   
    public PositionException(String message) {
        super(message);
    }
   
}

 

7.自定义异常
SalaryCalculatorException

 

package org.liky.junit.easymock;

public class SalaryCalculatorException extends RuntimeException {

    private static final long serialVersionUID = 4179482632698964011L;

    public SalaryCalculatorException() {
        super();
    }

    public SalaryCalculatorException(String message) {
        super(message);
    }
}

 

8.使用EasyMock与Junit4进行单元测试

 

package org.junit.easymock;

import static org.junit.Assert.fail;

import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.liky.junit.easymock.ISalaryCalculator;
import org.liky.junit.easymock.IncomeCalculator;
import org.liky.junit.easymock.Position;
import org.liky.junit.easymock.PositionException;

/**
 * 从EasyMock的工作原理可以看出,我们在设计程序的时候,
 * 应该尽量的将业务逻辑设计成接口,然后再提供实现
 * @author Abu
 *
 */


public class IncomeCalculatorTest {

    private ISalaryCalculator sc;
    private IncomeCalculator ic;
   
    @Before
    public void setUp() throws Exception {
        // 根据业务逻辑接口,使用EasyMock创建一个模拟对象


        sc = EasyMock.createMock(ISalaryCalculator.class);
        ic = new IncomeCalculator();
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    @Ignore
    public void testSetSalaryCalculator() {
        fail("Not yet implemented");
    }

    @Test
    @Ignore
    public void testSetPosition() {
        fail("Not yet implemented");
    }

    /**
     * 模拟职员类型为BOSS的情形,另外两种职员类型的测试与此相同,
     * 注意我们在这里并没有构造实现了ISalaryCalculator接口的
     * SalaryCalculator类的对象,而是通过EasyMock来模拟的
     */


    @Test
    public void testCalculate() {
        // 设置模拟对象的参数,即期望值


        EasyMock.expect(sc.calculate(Position.BOSS)).andReturn(10000d);
       
        // 激活模拟


        EasyMock.replay(sc);
       
        // 设置计算方法为EasyMock的模拟对象,这就是它的核心功能


        ic.setSalaryCalculator(sc);
       
        ic.setPosition(Position.BOSS);
       
        // 开始最终的断言


        Assert.assertEquals(10000, ic.calculate());
       
        // 验证模拟对象的方法是否已经执行


        EasyMock.verify(sc);
    }
   
    /**
     * 测试如果职员类型不是Position枚举中所列
     * 抛出异常的情形
     */


    @Test(expected=PositionException.class)   
    public void testCalculate2() {
        // 设置模拟对象的参数,即期望值


        EasyMock.expect(sc.calculate(Position.BOSS)).andReturn(10000d);
       
        // 激活模拟


        EasyMock.replay(sc);
       
        // 设置计算方法为EasyMock的模拟对象,这就是它的核心功能


        ic.setSalaryCalculator(sc);
       
        // 注释掉这一样,就没有指定职员类型


        //ic.setPosition(Position.BOSS);
       
        // 开始计算薪水,如果正常的话,这行代码将抛出PositionException


        double salary = ic.calculate();
       
        // 所以如果程序继续执行将导致失败


        Assert.fail("Sorry, no PositionException was thrown!");
    }

}

抱歉!评论已关闭.