基于Mockito框架单元测试
1、功能类
@Component
@Slf4j
public class LivePvuvCommonBusiness {
@Autowired
private LivePvUvService pvUvService;
@Autowired
private LiveSubRedisCommonBusiness liveSubRedisCommonBusiness;
@Autowired
ImService imService;
/**
* 获取直播点赞数
*
* @param liveId
* @return
*/
public int getLikePv(int liveId) {
int likePv = pvUvService.getPv(liveId, ChannelSource.ALL, PvUvCountEnum.LIKE_PV);
log.info("LivePvuvCommonBusiness->getLikePv直播={},获取点赞数={}", liveId, likePv);
return likePv;
}
/**
* 获取直播播放的次数
*
* @param
* @return
*/
public int getPlayPv(int liveId, int showFlag, String multiple, int baseNum) {
int playNum = pvUvService.getPv(liveId, ChannelSource.ALL, PvUvCountEnum.PLAY_PV);
log.info("LivePvuvCommonBusiness->getPlayPv直播={},数据开关={},播放次数={}", liveId, showFlag, playNum);
//数据填充
if (FlagEnum.YES.getValue() == showFlag) {
playNum = MathUtil.count(playNum, multiple, baseNum);
}
log.info("LivePvuvCommonBusiness->getPlayPv直播={},乘数后次数={}", liveId, playNum);
return playNum;
}
/**
* 根据实际值+公式计算虚拟值
*
* @param
* @return
*/
public int getTotleNumByNum(int num, int showFlag, String multiple, int baseNum) {
int TotleNum = num;
log.info("LivePvuvCommonBusiness->getTotleNumByNum数据开关={},初始值={}", showFlag, num);
//数据填充
if (FlagEnum.YES.getValue() == showFlag) {
TotleNum = MathUtil.count(num, multiple, baseNum);
}
log.info("LivePvuvCommonBusiness->getTotleNumByNum计算后数值={}", TotleNum);
return TotleNum;
}
/**
* 获取直播订阅数
*
* @param
* @return
*/
public int getSubPv(String liveIdstr, int showFlag, String multiple, int baseNum) {
//获取实际预约人数
int subscribeNum = liveSubRedisCommonBusiness.getCacheWechatSubCount(liveIdstr);
log.info("LivePvuvCommonBusiness->getSubPv直播={},数据开关={},实际预约人数={}", liveIdstr, showFlag, subscribeNum);
//数据填充
if (FlagEnum.YES.getValue() == showFlag) {
subscribeNum = MathUtil.count(subscribeNum, multiple, baseNum);
}
log.info("LivePvuvCommonBusiness->getSubPv直播={},乘数后预约人数={}", liveIdstr, subscribeNum);
return subscribeNum;
}
/**
* 获取在线人数
*
* @param
* @return
*/
public int getOnlinePv(int playPv, int showFlag, String multiple, int baseNum) {
int onlineNum = playPv;
log.info("LivePvuvCommonBusiness->getOnlinePv,数据开关={},实际在线人数={}", playPv, showFlag);
//数据填充
if (FlagEnum.YES.getValue() == showFlag) {
onlineNum = MathUtil.count(onlineNum, multiple, baseNum);
}
log.info("LivePvuvCommonBusiness->getOnlinePv乘数后预约人数={}", onlineNum);
return onlineNum;
}
/**
* 从rm直接获取在线人数
*
* @param
* @return
*/
public int getOnlinePvByIm(int roomId, int liveId, int showFlag, String multiple, int baseNum) {
ArrayList<Integer> objects = new ArrayList<>();
objects.add(roomId);
ImOnlineResp resp = imService.online(objects);
Map<Integer, Integer> map = resp.getItems().stream().collect(Collectors.toMap(
ImOnlineItemsDto::getRoomId, ImOnlineItemsDto::getNum, (t1, t2) -> t1));
int onlineNum = map.get(roomId);
log.info("LivePvuvCommonBusiness->getOnlinePv直播id={},数据开关={},实际在线人数={}", liveId, showFlag, onlineNum);
//数据填充
if (FlagEnum.YES.getValue() == showFlag) {
onlineNum = MathUtil.count(onlineNum, multiple, baseNum);
}
log.info("LivePvuvCommonBusiness->getOnlinePv直播={},乘数后预约人数={}", liveId, onlineNum);
return onlineNum;
}
/**
* 从rm直接获取在线人数
*
* @param
* @return
*/
public int getOnlinePvByOnlineNum(int onlineNum, int liveId, int showFlag, String multiple, int baseNum) {
log.info("LivePvuvCommonBusiness->getOnlinePv直播id={},数据开关={},实际在线人数={}", liveId, showFlag, onlineNum);
//数据填充
if (FlagEnum.YES.getValue() == showFlag) {
onlineNum = MathUtil.count(onlineNum, multiple, baseNum);
}
log.info("LivePvuvCommonBusiness->getOnlinePv直播={},实际在线人数={},乘数后预约人数={}", liveId, onlineNum);
return onlineNum;
}
}
2、单元测试类
public class LivePvuvCommonBusinessTest {
/**
* 测试类使用模拟对象(@Mock注解)来代替LivePvuvCommonBusiness类的依赖项:
* pvUvService,liveSubRedisCommonBusiness和imService。
*/
@Mock
private LivePvUvService pvUvService;
@Mock
private LiveSubRedisCommonBusiness liveSubRedisCommonBusiness;
@Mock
private ImService imService;
/**
* @InjectMocks注解用于将模拟对象(上面mock的对象)
* 自动注入livePvuvCommonBusiness实例。
*/
@InjectMocks
private LivePvuvCommonBusiness livePvuvCommonBusiness;
/**
* @BeforeEach注解的方法setup()用于在每个测试方法运行之前初始化模拟对象。
* initMocks初始化mock
*/
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetLikePv() {
//测试方法testGetLikePv()测试了LivePvuvCommonBusiness类的getLikePv()方法的行为。
//使用when...thenReturn来模拟pvUvService.getPv()方法的行为,当使用特定参数
// (1,ChannelSource.ALL和PvUvCountEnum.LIKE_PV)调用时返回结果100。
when(pvUvService.getPv(1, ChannelSource.ALL, PvUvCountEnum.LIKE_PV)).thenReturn(100);
//调用livePvuvCommonBusiness.getLikePv(1)方法,
//这应该在内部调用模拟的pvUvService.getPv()方法。
int likePv = livePvuvCommonBusiness.getLikePv(1);
// 验证结果, 断言getLikePv(1)的结果等于100,因为模拟的行为应该返回100。
assertEquals(100, likePv);
//最后,验证pvUvService.getPv()方法确实使用预期的参数(1,ChannelSource.ALL和PvUvCountEnum.LIKE_PV)被调用了一次。
verify(pvUvService, times(1)).getPv(1, ChannelSource.ALL, PvUvCountEnum.LIKE_PV);
//该测试的目的是验证LivePvuvCommonBusiness类的getLikePv()方法与pvUvService依赖项正确交互,
//并且在定义了模拟行为时返回预期结果。
}
@Test
public void testGetPlayPv() {
// 模拟pvUvService.getPv的行为,返回200作为播放PV
when(pvUvService.getPv(2, ChannelSource.ALL, PvUvCountEnum.PLAY_PV)).thenReturn(200);
// 调用待测试的方法
int playPv = livePvuvCommonBusiness.getPlayPv(2, FlagEnum.YES.getValue(), "2", 100);
// 验证结果
assertEquals(500, playPv); // 根据MathUtil.count方法计算 200 * 2 + 100 = 500
verify(pvUvService, times(1)).getPv(2, ChannelSource.ALL, PvUvCountEnum.PLAY_PV);
}
@Test
public void testGetTotleNumByNum(){
int totleNumByNum = livePvuvCommonBusiness.getTotleNumByNum(300, FlagEnum.YES.getValue(), "2", 100);
assertEquals(700,totleNumByNum);
}
@Test
public void testGetSubPv(){
// 模拟数据
// String liveIdstr = "123";
// int showFlag = FlagEnum.YES.getValue();
// String multiple = "3";
// int baseNum = 20;
// int expectedSubscribeNum = 60;
when(liveSubRedisCommonBusiness.getCacheWechatSubCount(Mockito.anyString())).thenReturn(100);
int totleNumByNum = livePvuvCommonBusiness.getSubPv(Mockito.anyString(), FlagEnum.YES.getValue(), "2", 100);
assertEquals(300,totleNumByNum);
verify(liveSubRedisCommonBusiness,times(1)).getCacheWechatSubCount(Mockito.anyString());
}
@Test
public void testGetOnlinePvByIm(){
// 模拟数据
int liveId = 123;
int showFlag = FlagEnum.YES.getValue();
String multiple = "3";
int baseNum = 30;
int roomId = 20;
int expectedOnlinePv = 60;
// 模拟imService.online方法的行为,返回包含房间ID和在线人数的ImOnlineResp对象
ArrayList<ImOnlineItemsDto> items = new ArrayList<>();
ImOnlineItemsDto imOnlineItemsDto = new ImOnlineItemsDto();
imOnlineItemsDto.setNum(10);
imOnlineItemsDto.setRoomId(roomId);
items.add(imOnlineItemsDto);
ImOnlineResp imOnlineResp = new ImOnlineResp();
imOnlineResp.setItems(items);
when(imService.online(Mockito.anyList())).thenReturn(imOnlineResp);
int onlinePvByIm = livePvuvCommonBusiness.getOnlinePvByIm(roomId, liveId, showFlag, multiple, baseNum);
assertEquals(expectedOnlinePv,onlinePvByIm);
verify(imService,times(1)).online(Mockito.anyList());
}
}
写完单元测试,是不是对TDD(测试驱动开发)也有点感觉了。先划分功能模块,编写mockito,每个功能模块拿到预期的值,带入组合功能方法中,最后获得整个功能的预期值。