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

Java如何不使用Powermock对未注入对象进行Mock编写单元测试

无需使用PowerMock,仅需对原有类做最小幅度的兼容式重构,即可通过Mockito完成mock,具体实现如下:

1. 重构原有Foo类

新增支持传入Client实例的构造方法,原有无参构造逻辑保持不变,完全兼容现有业务代码的调用方式,不会产生侵入性影响。如果不希望该构造方法对外公开,可去掉public修饰符改为包级私有,只要测试类和Foo类处于同一包下即可正常调用。

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Response;

public class Foo {
    private final Client http;

    // 原有无参构造,保留现有逻辑,不影响原有业务调用
    public Foo() {
        this(ClientBuilder.newClient().register(CurlRequestFactory.getCurlRequestFactory().get(LOGGER, "someString")));
    }

    // 新增构造方法,支持从外部传入Client实例,测试时传入mock对象即可
    public Foo(Client httpClient) {
        this.http = httpClient;
    }

    public void someMethod() {
        Invocation.Builder request = http.target(getURI("someUri")).request().header("someHeader", "someValue");
        Response response = request.get();
    }

    // 原有getURI实现保持不变
    private String getURI(String uri) {
        return uri;
    }
}

2. 单元测试实现

按代码中的调用顺序mock整条链路的对象,分别配置每个方法调用的返回值,最终实现调用request.get()时抛出指定异常的需求。如果使用JUnit5版本,可将@Test的expected参数替换为Assertions.assertThrows()方法做异常校验。

import org.junit.Test;
import org.mockito.Mockito;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

public class FooTest {

    @Test(expected = Exception.class)
    public void testSomeMethodThrowException() throws Exception {
        // 1. Mock整条调用链的对象
        Client mockClient = Mockito.mock(Client.class);
        WebTarget mockWebTarget = Mockito.mock(WebTarget.class);
        Invocation.Builder mockBuilder = Mockito.mock(Invocation.Builder.class);

        // 2. 按调用顺序配置mock返回值
        Mockito.when(mockClient.target(Mockito.eq("someUri"))).thenReturn(mockWebTarget);
        Mockito.when(mockWebTarget.request()).thenReturn(mockBuilder);
        Mockito.when(mockBuilder.header(Mockito.eq("someHeader"), Mockito.eq("someValue"))).thenReturn(mockBuilder);
        // 配置get方法抛出异常
        Mockito.when(mockBuilder.get()).thenThrow(new Exception("someMessage"));

        // 3. 用mock的Client构造Foo实例,调用方法验证
        Foo foo = new Foo(mockClient);
        foo.someMethod();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 02:27:04