使用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
相关产品推荐
相关产品推荐

