单元测试初窥门径

一、单元测试基本了解

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 的方法返回值。
相关推荐
Dnelic-14 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
世间万物皆对象21 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
Dnelic-1 天前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记
岳哥i1 天前
前端项目接入单元测试手册
前端·单元测试
qq_433716952 天前
Selenium+Pytest自动化测试框架 ------ 禅道实战
自动化测试·软件测试·selenium·单元测试·pytest·接口测试·压力测试
Dreams°1232 天前
【大数据测试ETL:从0-1实战详细教程】
大数据·数据仓库·python·单元测试·etl
敲代码敲到头发茂密2 天前
怎么做好白盒测试?
java·数据库·mysql·算法·单元测试·模块测试·测试覆盖率
Dreams°1235 天前
【大数据测试HDFS + Flask详细教程与实例】
大数据·功能测试·hdfs·单元测试·flask
CSXB997 天前
三十八、Python(pytest框架-上)
python·功能测试·测试工具·单元测试·pytest
伍肆伍柒7 天前
SpringBoot 2.2.10 无法执行Test单元测试
spring boot·后端·单元测试