Mockito:模拟测试框架的具体介绍与使用
Posted ABin-阿斌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mockito:模拟测试框架的具体介绍与使用相关的知识,希望对你有一定的参考价值。
我是 ABin-阿斌:写一生代码,创一世佳话,筑一揽芳华。 如果小伙伴们觉得我的文章不错,记得一键三连哦。
一、什么是Mockito
Mockito 是一个强大的用于 Java 开发的模拟测试框架, 通过 Mockito 我们可以创建和配置 Mock 对象,进而简化有外部依赖的类的测试。
二、有什么作用:
提前创建测试,TDD(测试驱动开发)
- 如果你创建了一个 Mock 那么你就可以在 service 接口创建之前写 Service Tests 了,这样你就能在开发过程中把测试添加到你的自动化测试环境中了。换句话说,模拟使你能够使用测试驱动开发。
团队可以并行工作
- 这类似于上面的那点;为不存在的代码创建测试。但前面讲的是开发人员编写测试程序,这里说的是测试团队来创建。当还没有任何东西要测的时候测试团队如何来创建测试呢?模拟并针对模拟测试!
- 这意味着当 service 接口需要测试时,实际上 QA 团队已经有了一套完整的测试组件;没有出现一个团队等待另一个团队完成的情况。这使得模拟的效益型尤为突出了。
你可以创建一个验证或者演示程序。
- 由于Mocks 非常高效,Mocks 可以用来创建一个概念证明,作为一个示意图,或者作为一个你正考虑构建项目的演示程序。这为你决定项目接下来是否要进行提供了有力的基础,但最重要的还是提供了实际的设计决策。
隔离系统
- 有时,你希望在没有系统其他部分的影响下测试系统单独的一部分。由于其他系统部分会给测试数据造成干扰,影响根据数据收集得到的测试结论。使用 mock 你可以移除掉除了需要测试部分的系统依赖的模拟。
- 当隔离这些 mocks 后,mocks 就变得非常简单可靠,快速可预见。这为你提供了一个移除了随机行为,有重复模式并且可以监控特殊系统的测试环境。
三、具体如何使用:
- 在使用 Mockito 测试框架时,我们需要提前在 idea 中装一个测试插件,这个插件会帮我们生成大部分的测试代码,从而减少我们的一个测试开发成本。
IntelliJ idea 需要安装的测试插件
当我们安装好这个插件后我们只需要选中我们想要测试的类——操作如下:
这里可以根据你们公司所规定的测试版本来,我这里用的是 JUnit5 和 Mockito
经过以上操作后,我们 ServiceImpl 中有几个方法,这个插件就会帮我们生成几个相对应的测试方法,当然这里我们还需要自己手动改一下
- init()和 最下面那个方法是通用的,其方法根据自己的实际情况来测试就可以了。下面看不懂的注解可以去查一下主要是 Junit5 和 Mockito测试框架
3.1 Mockito的API介绍
- 不懂的可以看看这几篇文章,我觉得写的都挺不错。
- MockitoAPI介绍
- Mockito中文文档
3.2案例解析:
要测试的 DtMachineIncomeServiceImpl 实现类
@Service
public class DtMachineIncomeServiceImpl extends ServiceImpl<DtMachineIncomeMapper, DtMachineIncomeEntity> implements DtMachineIncomeService {
@Autowired
private DtMachineAddressIncomeDayService dtMachineAddressIncomeDayService;
@Autowired
private DtMachineInfoService dtMachineInfoService;
@Override
public BigDecimal profitByTeamsAndCurrency(List<Long> teamIds, String currencyMark) {
DynamicTableParser.setId(currencyMark);
List<DtMachineIncomeEntity> machineIncomeEntityList = this.list(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
.in(DtMachineIncomeEntity::getOrganizationId, teamIds));
return machineIncomeEntityList.parallelStream().map(DtMachineIncomeEntity::getActualTotalIncome).reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Override
public DtMachineIncomeEntity getOneByOrganizationIdAndMachineId(Long organizationId, Long machineIdId) {
return this.getOne(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
.eq(DtMachineIncomeEntity::getOrganizationId, organizationId)
.eq(DtMachineIncomeEntity::getMachineId, machineIdId)
.last(MybatisPlusConst.LIMIT_1));
}
@Override
public boolean saveDtMachineIncome(DtMachineIncomeEntity entity) {
return this.save(entity);
}
@Override
public boolean updateByDtMachineIncomeId(DtMachineIncomeEntity entity) {
return this.updateById(entity);
}
@Override
public List<DtMachineIncomeEntity> listByTeamId(Long teamId) {
return this.list(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
.eq(DtMachineIncomeEntity::getOrganizationId, teamId));
}
@Override
public DtMachineIncomeEntity lastTimeByTeamIds(List<Long> teamIdsByUserId) {
return this.getOne(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
.in(DtMachineIncomeEntity::getOrganizationId, teamIdsByUserId)
.orderByDesc(DtMachineIncomeEntity::getUpdateTime)
.last(MybatisPlusConst.LIMIT_1));
}
@Override
public void updateMachineProfits(Long organizationId, Long machineIdd, DateTime dateTime, Integer type) {
DynamicTableParser.setId(CurrencyMarkEnum.ETH.getMark());
DtMachineIncomeEntity machineIncomeEntity = this.getOne(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
.eq(DtMachineIncomeEntity::getMachineId, machineIdd)
.eq(DtMachineIncomeEntity::getOrganizationId, organizationId));
if (ObjectUtil.isEmpty(machineIncomeEntity)) {
return;
}
DtMachineAddressIncomeDayEntity dtMachineAddressIncomeDayEntity = dtMachineAddressIncomeDayService.getOne(Wrappers.lambdaQuery(DtMachineAddressIncomeDayEntity.class)
.eq(DtMachineAddressIncomeDayEntity::getOrganizationId, organizationId)
.eq(DtMachineAddressIncomeDayEntity::getMachineId, machineIdd)
.between(DtMachineAddressIncomeDayEntity::getDayTime, DateUtil.beginOfDay(dateTime), DateUtil.endOfDay(dateTime)));
// 1-移动至 2-删除
if (type == 1) {
machineIncomeEntity.setTheoryIncome(BigDecimal.ZERO);
if (ObjectUtil.isNotEmpty(dtMachineAddressIncomeDayEntity)) {
dtMachineAddressIncomeDayEntity.setTheoryIncome(BigDecimal.ZERO);
dtMachineAddressIncomeDayEntity.setUpdateTime(dateTime);
dtMachineAddressIncomeDayService.updateById(dtMachineAddressIncomeDayEntity);
}
}
machineIncomeEntity.setActualComputingPower("0");
machineIncomeEntity.setTwentyFourAvgComputingPower("0");
machineIncomeEntity.setUpdateTime(dateTime);
this.updateById(machineIncomeEntity);
}
@Override
public List<DtMachineIncomeEntity> listByTeamIdNoRepeat(Long teamId) {
List<DtMachineIncomeEntity> returnList = new ArrayList<>();
List<DtMachineInfoEntity> machineInfoList = dtMachineInfoService.listByTeamId(teamId);
Map<Long, Long> count = machineInfoList.parallelStream().map(x -> x.getAddressId())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<DtMachineInfoEntity> noRepeatAddressIds = new ArrayList<>();
count.forEach((k, v) -> {
if (ObjectUtil.isNotEmpty(k)) {
DtMachineInfoEntity dtMachineInfoEntity = dtMachineInfoService.listByTeamIdAndAddressId(teamId, k);
noRepeatAddressIds.add(dtMachineInfoEntity);
}
});
if (ObjectUtil.isNotEmpty(noRepeatAddressIds)) {
for (DtMachineInfoEntity infoEntity : noRepeatAddressIds) {
DtMachineIncomeEntity oneByOrganizationIdAndMachineId = this.getOneByOrganizationIdAndMachineId(infoEntity.getOrganizationId(), infoEntity.getId());
if (ObjectUtil.isNotEmpty(oneByOrganizationIdAndMachineId)) {
returnList.add(oneByOrganizationIdAndMachineId);
}
}
}
return returnList;
}
@Override
public List<DtMachineIncomeEntity> listByTeamIds(List<Long> teamIds) {
return this.list(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
.in(DtMachineIncomeEntity::getOrganizationId, teamIds));
}
}
测试类:下面的代码结合上面实现代码看会好懂一点
@ExtendWith({SpringExtension.class, ExtentUtils.class})
class DtMachineIncomeServiceImplTest {
//除了我们测试类本身要真实的其它都可以进行 mock 模拟
@MockBean
DtMachineAddressIncomeDayService dtMachineAddressIncomeDayService;
@MockBean
DtMachineInfoService dtMachineInfoService;
@MockBean
DtMachineIncomeMapper dtMachineIncomeMapper;
//这个必须要真实的,因为这个是我们要测试的主体类
@Autowired
DtMachineIncomeServiceImpl dtMachineIncomeServiceImpl;
@BeforeAll
public static void init() {
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), DtMachineIncomeEntity.class);
}
@Test
@DisplayName("根据组织id集合,币种返回实际总收益")
void testProfitByTeamsAndCurrency() {
BigDecimal result = dtMachineIncomeServiceImpl.profitByTeamsAndCurrency(Arrays.<Long>asList(Long.valueOf(1)), "currencyMark");
Assertions.assertEquals(new BigDecimal(0), result);
}
@Test
@DisplayName("根据矿机id,组织id返回一天记录")
void testGetOneByOrganizationIdAndMachineId() {
//模拟当第一次当用这个方法时,返回这个:new DtMachineIncomeEntity()
//any():表示所有、任何
when(dtMachineIncomeServiceImpl.getOne(any())).thenReturn(new DtMachineIncomeEntity());
DtMachineIncomeEntity result = dtMachineIncomeServiceImpl.getOneByOrganizationIdAndMachineId(Long.valueOf(1), Long.valueOf(1));
//判断是否相等
Assertions.assertEquals(new DtMachineIncomeEntity(), result);
}
@Test
@DisplayName("保存对象")
void testSaveDtMachineIncome() {
//模拟调用方法,返回 1
when(dtMachineIncomeMapper.insert(any())).thenReturn(1);
boolean result = dtMachineIncomeServiceImpl.saveDtMachineIncome(new DtMachineIncomeEntity());
Assertions.assertEquals(true, result);
}
@Test
@DisplayName("根据id修改")
void testUpdateByDtMachineIncomeId() {
when(dtMachineIncomeMapper.updateById(any())).thenReturn(1);
boolean result = dtMachineIncomeServiceImpl.updateByDtMachineIncomeId(new DtMachineIncomeEntity());
Assertions.assertEquals(true, result);
}
@Test
@DisplayName("根据小组集合返回列表")
void testListByTeamId() {
when(dtMachineIncomeServiceImpl.list(any())).thenReturn(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()));
List<DtMachineIncomeEntity> result = dtMachineIncomeServiceImpl.listByTeamId(Long.valueOf(1));
Assertions.assertEquals(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()), result);
}
@Test
@DisplayName("返回最新更新时间")
void testLastTimeByTeamIds() {
when(dtMachineIncomeServiceImpl.getOne(any())).thenReturn(new DtMachineIncomeEntity());
DtMachineIncomeEntity result = dtMachineIncomeServiceImpl.lastTimeByTeamIds(Arrays.<Long>asList(Long.valueOf(1)));
Assertions.assertEquals(new DtMachineIncomeEntity(), result);
}
@Test
@DisplayName("ETH删除(移动至)矿机收益算力操作")
void testUpdateMachineProfits() {
dtMachineIncomeServiceImpl.updateMachineProfits(Long.valueOf(1), Long.valueOf(1), null, Integer.valueOf(0));
}
@Test
@DisplayName("根据小组集合返回列表")
void testListByTeamIdNoRepeat() {
DtMachineInfoEntity mock = JMockData.mock(DtMachineInfoEntity.class);
List<DtMachineInfoEntity> dtMachineInfos = new ArrayList<>();
dtMachineInfos.add(mock);
when(dtMachineInfoService.listByTeamId(any())).thenReturn(dtMachineInfos);
when(dtMachineInfoService.listByTeamIdAndAddressId(any(), any())).thenReturn(mock);
DtMachineIncomeEntity mock1 = JMockData.mock(DtMachineIncomeEntity.class);
when(dtMachineIncomeServiceImpl.getOne(any())).thenReturn(mock1);
List<DtMachineIncomeEntity> result = dtMachineIncomeServiceImpl.listByTeamIdNoRepeat(Long.valueOf(1));
Assertions.assertEquals(Arrays.<DtMachineIncomeEntity>asList(mock1), result);
}
@Test
@DisplayName("根据组织ID列表查询在矿机收益中是否存在数据")
void testListByTeamIds() {
when(dtMachineIncomeServiceImpl.list(any())).thenReturn(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()));
List<DtMachineIncomeEntity> result = dtMachineIncomeServiceImpl.listByTeamIds(Arrays以上是关于Mockito:模拟测试框架的具体介绍与使用的主要内容,如果未能解决你的问题,请参考以下文章