栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mockito使用问题记录

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mockito使用问题记录

一、背景

公司在用Mockito进行单元测试,写单测的时候总会遇到一些小问题,顺手记录下来。

二、遇到问题记录 2.1 mock update 报错 2.1.1 问题现象

当update使用如下写法时,mock会报错
被mock代码示例:

mock语句:

when(platformMallOrderServcie.update(any())).thenReturn(true);

报错:

ERROR com.longfor.gf.lw.ordercenter.business.OrderBusiness - callbackMerchant回调异常,原因:cannot find column’s cache for “com.longfor.gf.lw.ordercenter.entity.PlatformMallOrder”, so you cannot used “class com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper”!
com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: cannot find column’s cache for “com.longfor.gf.lw.ordercenter.entity.PlatformMallOrder”, so you cannot used “class com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper”!

2.1.2 问题原因

根据测试,发现只有update时使用lambda进行set操作会有问题。推测是mock框架和mybatis-plus框架有冲突。

2.1.3 解决方案

解决方法有两个,两种方案均可实现mock不报错。

第一种解决方案:修改update写法
不使用lambda即可。修改后代码如下:

第二种解决方案:修改mock方法
除非mock时发现代码有问题,一般情况下,不会因为mock修改代码,那么就要修改mock方法。报错中提示是目标类没有加载进mybatis-plus的缓存中,那么mock时手动将其加载进缓存即可。代码如下:

根据版本号选择
TableInfoHelper.initTableInfo(null, PlatformMallOrder.class);
或
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), RefundTradeProcessPool.class);

改后如下:

TableInfoHelper.initTableInfo(null, PlatformMallOrder.class);
when(platformMallOrderServcie.update(any())).thenReturn(true);

注:如果有其他方案,欢迎大家补充。

2.2 mock mybatis-plus生成的service报错 2.2.1 问题现象

以PlatformMallGoodsServiceImpl类为例。此类定义如下

public class PlatformMallGoodsServiceImpl extends ServiceImpl implements IPlatformMallGoodsService

所以应该mock对应的mapper方法

when(platformMallGoodsMapper.update(any(PlatformMallGoods.claaa),any(UpdateWrapper.class))).thenReturn(1);

代码中有如下写法,mock时会报空指针

this.update(goodsUpdateWrapper)
2.2.2 查找问题点

通过debug可以找到对应的报错代码

发现是mapper没有注进去。

2.2.3 问题原因

原因是使用的注解不同

// mock目标类的注解
@InjectMocks
private PlatformMallGoodsServiceImpl platformMallGoodsService;
// 其他被mock的类
@Mock
private ISecondhandGoodsDetailService secondhandGoodsDetailService;

@InjectMocks标记的类会被实例化,@Mock标记的类会被注入到@InjectMocks标记的类中。

2.2.4 解决方案

mock方法中手动注入mapper即可,代码写法如下

ReflectionTestUtils.setField({@InjectMocks标记的类}, "baseMapper", {@InjectMocks标记的类对应的mapper});

按照上述写法,此例中添加的mock代码如下

ReflectionTestUtils.setField(platformMallGoodsService, "baseMapper", platformMallGoodsMapper);
2.3 mock List失败 2.3.1 问题现象

@Mock一个List变量不生效,代码如下

@Mock
private List mockStrategies;

在真正运行时会报NPE,因为strategies为null,报错代码如下

for (TimeFormatStrategy strategy : strategies) 
2.3.2 问题原因

具体原因没有找到,我观察到在单测方法中list会被mock出来,但走到真正的方法内list就变成null了,仿佛mock没有生效。
参见:如何mock一个List类型的属性

2.3.3 解决方案

将@Mock换成@Spy注解,然后增加一个赋值逻辑即可

@Spy
private List mockStrategies = new ArrayList<>();
// 不用一定放到Before里,放在对应的Test方法中也可以,我是懒得一个一个放就这么写了
@Before
public void init() {
    mockStrategies.add(mockDefaultTimeFormatStrategy);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/992680.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号