单元测试初窥门径

一、单元测试基本了解

1. Mock概念

据百度百科:mock测试就是在测试过程中,对于某些不容易构造或者容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。

2. powermock框架

单元测试(Unit Testing)是一种软件测试方法,是在软件开发过程中对软件模块进行校验的测试工作。

powermock 是Java 单元测试的一个框架,主要用于帮助开发者进行单元测试时模拟静态、私有、final等方法。

powermock 的主要功能有:

  • 模拟静态方法、构造函数、私有方法等的行为。
  • 跳过静态初始化器。
  • 验证私有方法、静态方法等的调用次数、参数等。
  • 替换静态方法、构造函数的实现逻辑等。

3. 常用注解

@PrepareForTest :

示例:

java 复制代码
@PrepareForTest({FlightMarketUtil.class})

官方解释是当我们虚拟构造final、static、等方法时加以注解。

这里我们mock调用的方法包(FlightMarketUtil)里面的方法都是静态,必然需要加入此注解。一般我们自己的方法包都要加入此注解。

@SuppressStaticInitializationFor : 忽略静态类不必要的初始化

示例:

java 复制代码
@SuppressStaticInitializationFor({"com.umetrip.data.UmeFlightTopology.base.scheduledload.FlightMarketUtil"})

官方解释是用此注解的方式来阻止静态代码块中代码的执行。

这个里面全是静态代码,也就是说我们调用这个包的方法去执行的话在测试类中不会真正执行。也不用担心不会返回结果,有指定方法返回结果的。

@mock:

由Mockito框架根据接口的实现帮我们mock一个虚假对象,该对象的方法不会真正去执行。对函数的调用均执行mock(即虚假函数),不执行真正部分。

@InjectMocks

由Mockito框架根据接口的实现帮我们创建一个实例对象(注意是实例对象,所以调用该类的方法都会被执行 )。简单的说是这个Mock可以调用真实代码的方法。

二、Mock方法架构

待测试代码

java 复制代码
public class UmeB2SService {

    public UmePsrSubscribeEnum sendConsentinfo(B2sConsentinfo b2sConsentinfo);
 }
\ .........
@Autowired
private UmeB2SService umeB2SService;
UmePsrSubscribeEnum umePsrSubscribeEnum = umeB2SService.sendConsentinfo(b2sConsentinfo);

也就是说,我们要调用 umeB2SService.sendConsentinfo方法,覆盖这段代码。

1、新建方法继承 extends PowerMockTestCase

scala 复制代码
public class B2SProxyTest extends PowerMockTestCase {

}

2、测试执行加注解@Test

java 复制代码
public class B2SProxyTest extends PowerMockTestCase {
    @Test
    public void Test(){
    
    }
}

3、调用方法测试

java 复制代码
public class UmeB2SServiceTest  extends PowerMockTestCase {
    @InjectMocks
    private UmeB2SService umeB2SService;
    
    @Test
    public void Test() {
        
        B2sConsentinfo b2sConsentinfo = generateB2sConsentinfo("NI", "*******", "崔****", "Dave");
        UmePsrSubscribeEnum umePsrSubscribeEnum = umeB2SService.sendConsentinfo(b2sConsentinfo);

    }

一般其他的方法直接调用就可以,但是这个是UmeB2SService,一个@Service注解的内容,需要@InjectMocks注解,

三、常见测试方法

1、常用非静态方法

待Mock代码块

java 复制代码
SendResult res = messageProducer.send(normalMessage);

这是原本的业务代码,使用 messageProducer 的 send 方法发送消息。

(1)测试类mock 对应类

java 复制代码
@Mock
MessageProducer messageProducer;

@Mock
SendResult sendResult;

使用 @Mock 注解模拟 MessageProducer 和 SendResult 两个类。

(2)单测代码

java 复制代码
PowerMockito.when(messageProducer.send(Mockito.any())).thenReturn(sendResult);

使用 PowerMockito 的 when 方法,指定 messageProducer 的 send 方法在被调用时返回 sendResult。

2、静态方法

待Mock代码块

java 复制代码
private static MessageProducer messageProducer;
messageProducer = MessageProducerBuilder.createBuilder().setProducerConfig(props).build();

原本代码使用 MessageProducerBuilder 的静态方法创建 MessageProducer 实例。

(1)加注解(后续需要Mock静态方法时必需)

java 复制代码
@PrepareForTest({MessageProducerBuilder.class})

加入 @PrepareForTest 注解,表示会模拟 MessageProducerBuilder 类的静态方法。

(2)测试类mock 对应类

less 复制代码
@Mock
MessageProducer messageProducer;

@Mock
MessageProducerBuilder messageProducerBuilder;

使用 @Mock 注解模拟 MessageProducerBuilder 和 MessageProducer 类。

(3)Mock类

java 复制代码
PowerMockito.mockStatic(MessageProducerBuilder.class);

使用 PowerMockito.mockStatic() 方法模拟 MessageProducerBuilder 类。

(4)单测代码

java 复制代码
PowerMockito.when(MessageProducerBuilder.createBuilder()).thenReturn(messageProducerBuilder);
PowerMockito.when(MessageProducerBuilder.createBuilder().setProducerConfig(Mockito.any())).thenReturn(messageProducerBuilder);
PowerMockito.when(MessageProducerBuilder.createBuilder().setProducerConfig(Mockito.any()).build()).thenReturn(messageProducer);

使用 when 方法分别指定 MessageProducerBuilder 的静态方法在被调用时的返回值。注意这里的多重调用一定要每次调用都mock,不然会报空指针。

3、Service接口方法

(1)测试类中mock

java 复制代码
@Mock
private AirlineService airlineService;

使用 @Mock 注解模拟 AirlineService 接口。

(2)mock代码块

java 复制代码
Whitebox.setInternalState(priceService, "airlineService", airlineService);
PowerMockito.when(airlineService.getAirlineRouteList(anyString())).thenReturn(airlineRoutePoList);
  1. 使用 Whitebox 将 airlineService 注入 priceService。
  2. 使用 when 指定 airlineService 的方法返回值。
相关推荐
Python私教9 小时前
鸿蒙应用的测试和调试完全指南:从单元测试到性能分析
华为·单元测试·harmonyos
realhuizhu1 天前
周五下午5点改完的代码,你敢直接发布上线吗?
自动化测试·单元测试·ai编程·测试驱动开发·代码质量
我一定会有钱1 天前
pytest测试框架基础
python·单元测试·自动化·pytest
宋情写1 天前
单元测试、覆盖率测试-Springboot
spring boot·单元测试·测试覆盖率
卓码软件测评3 天前
第三方APP软件测试机构:【Gatling如何测试移动应用后端API移动网络特性和用户行为模拟】
网络·测试工具·单元测试·测试用例
晚烛3 天前
Flutter + OpenHarmony 质量保障体系:从单元测试到真机巡检的全链路可靠性工程
flutter·单元测试
旺仔Sec3 天前
2025年安徽省职业院校技能大赛(高职组)软件测试赛项规程及竞赛样题(附评分标准)
功能测试·单元测试·压力测试
記億揺晃着的那天5 天前
MyBatis-Plus 单元测试中 Lambda Mock 的坑与解决
单元测试·log4j·mybatis
CeshirenTester6 天前
Playwright元素定位详解:8种定位策略实战指南
人工智能·功能测试·程序人生·单元测试·自动化
行走的陀螺仪6 天前
Vue3 项目单元测试全指南:价值、Vitest 落地与提效方案
开发语言·前端·单元测试·html5·vitest