使用EasyMock进行单元测试

 

 

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!");
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值