You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TestNG与Surefire插件执行Maven测试失败求助

TestNG测试在IDEA正常但Maven执行失败(UnfinishedStubbing)问题排查

问题详情

编写的TestNG测试方法在IntelliJ IDEA中直接运行正常,但通过Maven test命令执行时抛出UnfinishedStubbing异常。

测试代码

@Test
public void testSendWebhook() throws KafkaConsumerException {
    PodamFactory factory = new PodamFactoryImpl();
    WebhookEventDTO<MeetingEventPayload> webhookEventDTO = factory.manufacturePojo(WebhookEventDTO.class, MeetingEventPayload.class);
    Mockito.when(u2CBizService.getWebhookFeatureToggleEndpoint(any(), any(), eq("webhook-engine"), any())).thenReturn("https://www.ciscospark.com/v1");
    Mockito.doNothing().when(webhookFeignClient).sendWebhookEvent(any(), any(), any());
    webhookRemoteService.sendWebhook(webhookEventDTO, "trackingId");
    Mockito.verify(webhookFeignClient, Mockito.times(1)).sendWebhookEvent(any(), any(), any());
} 

报错信息

[ERROR]   WebinarFeignServiceTest.testHeaderInterceptor:44 » UnfinishedStubbing 
Unfinished stubbing detected here:
-> at com.cisco.webex.notificationservice.remote.webhook.WebhookRemoteServiceTest.testSendWebhook(WebhookRemoteServiceTest.java:45)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed

POM相关配置

TestNG依赖

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.7.1</version>
    <scope>test</scope>
</dependency>

Maven Surefire插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven-surefire-plugin.version}</version>
    <configuration>
        <trimStackTrace>false</trimStackTrace>
        <includes>
            <include>**/*Test.java</include>
            <include>**/*Tests.java</include>
        </includes>
        <useUnlimitedThreads>true</useUnlimitedThreads>
        <reportFormat>plain</reportFormat>
        <testFailureIgnore>true</testFailureIgnore>
    </configuration>
</plugin>

可能的原因及解决办法

1. 多线程测试导致Mock状态混乱

Maven Surefire配置了<useUnlimitedThreads>true</useUnlimitedThreads>,会并行执行测试用例,而Mockito默认Mock实例非线程安全,多测试并行时易干扰Stubbing状态。

解决办法:

  • 暂时关闭多线程:将<useUnlimitedThreads>改为false,或设置固定线程数如<threadCount>4</threadCount>,重新执行测试验证。
  • 保留并行测试时,确保每个测试方法的Mock实例独立:通过@BeforeMethod初始化Mock,而非@BeforeClass,避免测试间状态共享。

2. Mockito与TestNG/Surefire版本不兼容

未明确的Mockito版本可能与TestNG 7.7.1或Surefire插件版本冲突,导致Maven环境下Stubbing逻辑异常。

解决办法:

  • 检查并添加兼容的Mockito依赖(推荐4.x或5.x版本):
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>

3. 测试类初始化顺序问题

IDEA与Maven Surefire的测试类初始化顺序不同,可能导致Mock未正确初始化,或其他测试类干扰当前测试的Mock状态。

解决办法:

  • 在测试类中添加@BeforeMethod,确保每次测试前重新初始化所有Mock:
@BeforeMethod
public void setup() {
    u2CBizService = Mockito.mock(U2CBizService.class);
    webhookFeignClient = Mockito.mock(WebhookFeignClient.class);
    webhookRemoteService = new WebhookRemoteService(u2CBizService, webhookFeignClient);
    // 其他需初始化的对象
}
  • 避免使用静态Mock实例,静态变量会在类加载时初始化,并行测试易引发状态共享问题。

4. Final方法Stubbing未开启支持

报错提示可能涉及Stub final方法,Mockito默认不支持此操作,需开启inline模式。

解决办法:

  • 在src/test/resources下创建mockito-extensions/org.mockito.plugins.MockMaker文件,写入内容:
mock-maker-inline
  • 确保Mockito版本在2.15.0及以上,支持inline模式。

5. 测试执行范围导致的干扰

Surefire的<includes>配置会执行多个测试类,并行时其他测试的不完整Stubbing可能干扰当前测试。

解决办法:

  • 单独运行当前测试类验证:
mvn test -Dtest=WebhookRemoteServiceTest
  • 若单独执行正常,说明是并行测试的状态污染,参考第1点处理。

内容的提问来源于stack exchange,提问作者user22990582

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:48:23