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

Java8+Maven3.9下PowerMock验证私有void方法遇NoSuchMethodError

问题:PowerMock验证私有void方法调用时出现NoSuchMethodError

环境与需求

  • Java 8
  • Maven 3.9
  • 需求:验证私有void方法logEvent的调用情况,使用PowerMock实现

现有配置与代码

pom.xml依赖

<properties>
    <powermock.version>2.0.2</powermock.version>
</properties>

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
    <version>4.4.0</version>
</dependency>

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <scope>test</scope>
    <version>4.4.0</version>
</dependency>

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>

服务类MyService

public class MyService {

    private String data;

    public MyService(String data) {
        this.data = data;
    }

    public void processData() {
        // Some processing logic
        String message = "Processing data: " + data;
        logEvent(message);
        // More processing logic
    }

    private void logEvent(String message) {
        // In a real scenario, this would log the event
        System.out.println("Logging: " + message);
    }
}

测试类MyServiceTest

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyService.class) // Prepare MyService for bytecode manipulation
public class MyServiceTest {

    @Test
    public void testProcessData_shouldCallLogEvent() throws Exception {
        // Arrange
        String testData = "sampleData";
        MyService service = new MyService(testData);
        MyService spyService = PowerMockito.spy(service); // Create a spy to track private method calls

        // Act
        spyService.processData(); // HERE ERROR!!!

        // Assert
        // Verify that the private method 'logEvent' was called exactly once
        verifyPrivate(spyService, times(1)).invoke("logEvent", "Processing data: sampleData");
    }
}

错误信息

java.lang.NoSuchMethodError: org.mockito.invocation.InvocationFactory.createInvocation(Ljava/lang/Object;Lorg/mockito/mock/MockCreationSettings;Ljava/lang/reflect/Method;Ljava/util/concurrent/Callable;[Ljava/lang/Object;)Lorg/mockito/invocation/Invocation;

    at com.myproject.handler.MyService.processData(MyService.java:15)
    at com.myproject.handler.MyService.processData(MyService.java:14)
    at com.myproject.handler.MyServiceTest.testProcessData_shouldCallLogEvent(MyServiceTest.java:26)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)

问题原因

PowerMock 2.0.2与Mockito 4.4.0存在版本兼容性问题。PowerMock 2.x系列仅支持Mockito 2.x到3.x版本,无法适配Mockito 4.x的API变更,导致反射调用时找不到对应方法。

解决方案

1. 调整依赖版本

将Mockito版本降级到PowerMock 2.0.2支持的最高版本(Mockito 3.12.4),同时移除mockito-inline依赖(PowerMock的字节码操作已覆盖其功能)。修改后的pom.xml依赖如下:

<properties>
    <powermock.version>2.0.2</powermock.version>
    <mockito.version>3.12.4</mockito.version>
</properties>

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
    <version>${mockito.version}</version>
</dependency>

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>

2. 验证测试代码

无需修改原有测试逻辑,调整依赖后直接运行测试即可。PowerMock将正常跟踪私有方法调用并完成验证。

结果

调整依赖后,testProcessData_shouldCallLogEvent测试将成功通过,确认私有方法logEvent被调用了1次。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:04:57