当前位置: 首页 > 工具软件 > easyMock > 使用案例 >

EasyMock测试

冯福
2023-12-01

一、Mock定义
日常测试过程中,对一些不容易构造的对象,通过mock模拟对象的行为。例如A,B两个模块,A依赖B,B未开发完成,通过mockB对象,返回预期的结果给A调用。

二、Easymock

原理:Easymock通过动态代理实现模拟对象的创建

2.1 Maven中添加EasyMock依赖

<dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>4.3</version>
    <scope>test</scope>
</dependency>

2.2 将查询接口注释

/**
 * @author:jack
 * @date 2021/5/30 19:25
 * @des:todo
 */
@Service
public class GoodsService {
    @Autowired
    GoodDao goodDao;

    //新增商品(注释内部实现,测试mock调用)
    public void insert(Goods goods){
//        return goodDao.insert(goods);
    }

    //查询所有商品(注释内部实现,测试mock调用)
    public List<Goods> queryGoodList(){
//        return goodDao.queryGoodList();
    }

    //根据id查询商品信息(注释内部实现,测试mock调用)
    public Goods queryById(int id){
//        return goodDao.queryById(id);
    }
}

2.3 通过mock创建查询接口

 @Test
    public void testQueryGoodById(){
        //创建期待的结果
        Goods goods1 = new Goods();
        goods1.setId(5);
        goods1.setGoodName("电脑");
        goods1.setGoodNum(99);
        goods1.setGoodDes("这是一台电脑");
        //1、创建Mock对象
        GoodsService mock = EasyMock.createMock(GoodsService.class);
        //2、模拟调用该mock对象抛出异常
        //EasyMock.expect(mock.queryById(5)).andThrow(new RuntimeException());
        //3、调用mock对象中的queryById接口进行模拟,EasyMock.anyInt())限制输入类型,根据数据类型,支持:anyInt(),anyShort(),anyByte(),angLong()...
        // EasyMock.expect(mock.queryById(EasyMock.anyInt())).andReturn(goods1);
        //4、测试该mock对象调用次数
        EasyMock.expect(mock.queryById(5)).andReturn(goods1).times(3);
        //5、重放Mock对象,将录制的对象代替真实的对象
        EasyMock.replay(mock);
        Goods good = mock.queryById(5);
        //预期值和实际值进行断言
        Assert.assertEquals(goods1,good);
        //验证mock对象被调用
        EasyMock.verify(mock);

注:
1、通过mock模拟GoodsService,mock调用queryById返回预期的结果,并进行断言。

2、EasyMock.createMock():必须用指定的参数调用指定的方法,不考虑调用方法的次序,调用未预期的方法会导致失败。
EasyMock.createStrictMock():必须按次序调用指定的方法,调用未逾期的方法会失败。

 GoodsService mock = EasyMock.createMock(GoodsService.class);

3、通过EasyMock.anyInt()对传入参数进行校验,类似泛型,还支持:EasyMock.anyShort()、EasyMock.anyByte()、EasyMock.anyLong()、EasyMock.anyFloat()、EasyMock.anyDouble()、EasyMock.anyBoolean(),输入类型不符的参数会报错。

EasyMock.expect(mock.queryById(EasyMock.anyInt())).andReturn(goods1);

4、 通过andReturns设置调用后返回的结果。

EasyMock.expect(mock.queryById(5)).andReturn(goods1);

5、测试方法调用的次数,与预期次数不符报错。

EasyMock.expect(mock.queryById(5)).andReturn(goods1).times(3);

6、模拟调用方法返回异常信息(常用)

EasyMock.expect(mock.queryById(5)).andThrow(new RuntimeException());
EasyMock.replay(mock);
Goods goods = mock.queryById(5);
Assert.assertNull(goods);
EasyMock.verify(mock);

2.4 mock无返回值对象
将GoodService中的insert()方法改为无返回值(应该为Boolean类型)
此时想mock插入对象的插入方法,需要进行修改:
正常mock:

mock.insert(goods);
EasyMock.expectLastCall().anyTimes();

异常mock:

EasyMock.expectLastCall().anyTimes();
EasyMock.expectLastCall().andThrow(new RuntimeException()).anyTimes();

2.5 mock多次调用返回不同的值
在测试用例的执行中,会有需求多次运行的过程中返回不同的值,这里简单举例:

EasyMock.expect(queryGoodList.next()).andReturn(true).times(5).andReturn(false).times(2);

三、总结
测试过程中,mock能大大的提高我们的效率,模拟各种想要的参数,得到想要的结果,但是会隐藏mock对象中较多的bug,导致测试不充分。在任何情况下,mock都不应该是我们的第一选择,在真实存在的场景下进行测试,才能发现更多的问题。
本文简单的介绍Easymock的使用,基本覆盖常用的mock场景,有兴趣深入的同学可阅读此篇文章:https://tech.youzan.com/mock/。

 类似资料: