Mockito 是一个流行的 Java 模拟测试框架,用于创建和管理测试中的模拟对象(mock objects)。它可以帮助开发者编写干净、可维护的单元测试,特别是在需要隔离被测组件与其他依赖项时。
目录
[1. 模拟对象(Mock Objects)](#1. 模拟对象(Mock Objects))
[2. 打桩(Stubbing)](#2. 打桩(Stubbing))
[3. 验证(Verification)](#3. 验证(Verification))
[1. 测试准备](#1. 测试准备)
[2. 模拟依赖(Mock)](#2. 模拟依赖(Mock))
[3. 执行测试](#3. 执行测试)
[4. 验证结果](#4. 验证结果)
[5. 验证收藏数增加](#5. 验证收藏数增加)
核心概念
1. 模拟对象(Mock Objects)
模拟对象是真实对象的替代品,用于在测试中模拟真实对象的行为,而不需要实际调用真实对象。
2. 打桩(Stubbing)
定义模拟对象在特定条件下的行为,即当调用某个方法时返回什么值或抛出什么异常。
3. 验证(Verification)
验证模拟对象的特定方法是否被调用,以及调用的次数和参数是否符合预期。
下面进行实际操作
等待测试的源码:
java
@Override
public JSONReturn save(Collect collect) {
Collect exist = collectMapper.selectExist(collect.getUserId(),collect.getForumId());
if(exist != null){
return JSONReturn.failed("操作失败,您已收藏该帖子!");
}
Date date = new Date();
collect.setCreateTime(date);
collect.setUpdateTime(date);
collectMapper.insert(collect);
// //收藏+1
Forum forum = forumMapper.selectByPrimaryKey(collect.getForumId());
forum.setCollectNum(forum.getCollectNum() + 1);
forumMapper.updateByPrimaryKeySelective(forum);
return JSONReturn.success("收藏成功!");
}
以下下是mock的代码
java
@Test
void save_shouldReturnSuccess_whenCollectNotExists() {
Collect collect = new Collect();
collect.setUserId(2);
collect.setForumId(9);
when(collectMapper.selectExist(2, 9)).thenReturn(null);
Forum forum = new Forum();
forum.setCollectNum(0);
when(forumMapper.selectByPrimaryKey(9)).thenReturn(forum);
JSONReturn result = collectService.save(collect);
assertEquals("收藏成功!", result.getMsg()); // Should return success message
verify(collectMapper, times(1)).selectExist(2, 9);
verify(collectMapper, times(1)).insert(collect);
verify(forumMapper, times(1)).updateByPrimaryKeySelective(any(Forum.class));
ArgumentCaptor<Forum> forumCaptor = ArgumentCaptor.forClass(Forum.class);
verify(forumMapper).updateByPrimaryKeySelective(forumCaptor.capture());
Integer collectNum = forumCaptor.getValue().getCollectNum();
assertEquals(new Integer(1), collectNum);
}
这是一个单元测试方法,测试当收藏记录不存在时成功保存收藏的功能。下面是对代码的逐步解释:
1. 测试准备
java
Collect collect = new Collect();
collect.setUserId(2);
collect.setForumId(9);
创建一个新的收藏对象,设置用户ID为2,论坛ID为9。
2. 模拟依赖(Mock)
java
when(collectMapper.selectExist(2, 9)).thenReturn(null);
模拟collectMapper.selectExist(2, 9)
方法调用,返回null表示该收藏记录不存在。
java
Forum forum = new Forum();
forum.setCollectNum(0);
when(forumMapper.selectByPrimaryKey(9)).thenReturn(forum);
创建一个论坛对象,设置收藏数为0,并模拟forumMapper.selectByPrimaryKey(9)
返回这个论坛对象。
3. 执行测试
java
JSONReturn result = collectService.save(collect);
调用被测试的collectService.save()
方法。
4. 验证结果
java
assertEquals("收藏成功!", result.getMsg());
验证返回的消息是"收藏成功!"。
java
verify(collectMapper, times(1)).selectExist(2, 9);
verify(collectMapper, times(1)).insert(collect);
验证:
-
selectExist
方法被调用了一次 -
insert
方法被调用了一次
java
verify(forumMapper, times(1)).updateByPrimaryKeySelective(any(Forum.class));
验证updateByPrimaryKeySelective
方法被调用了一次。
5. 验证收藏数增加
java
ArgumentCaptor<Forum> forumCaptor = ArgumentCaptor.forClass(Forum.class);
verify(forumMapper).updateByPrimaryKeySelective(forumCaptor.capture());
Integer collectNum = forumCaptor.getValue().getCollectNum();
assertEquals(new Integer(1), collectNum);
使用ArgumentCaptor
捕获传递给updateByPrimaryKeySelective
的Forum对象,验证其收藏数从0增加到了1。
总结
这个测试验证了当用户收藏一个尚未收藏的论坛时:
-
系统会检查该收藏记录是否存在
-
如果不存在则创建新收藏记录
-
更新论坛的收藏数(+1)
-
返回成功消息
测试覆盖了收藏服务的主要逻辑路径,确保在收藏记录不存在时的正确行为。