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

如何在Mockito中模拟经JaxWsProxyFactoryBean转换的GenericService对象?

问题根源

你遇到的问题和类型转换无关——isValidCode方法内部直接实例化JaxWsProxyFactoryBean并创建GenericService真实代理对象,导致你mock的GenericService实例根本没有被用到,测试时自然会调用实际的Web服务方法。

解决方案

推荐通过重构代码解耦服务创建逻辑,让测试时能够替换为mock对象,以下是几种可行方案:

方案1:抽离服务创建逻辑为可重写方法

在原类中将GenericService的创建逻辑抽成protected方法,测试时通过子类重写该方法返回mock对象:

重构原类

public class YourClass {
    private String genericServiceName;

    // 抽离服务创建逻辑,方便测试重写
    protected GenericService createGenericService() {
        JaxWsProxyFactoryBean proxy = new JaxWsProxyFactoryBean();
        proxy.setServiceClass(GenericService.class);
        proxy.setServiceName(new QName(this.genericServiceName));
        // 其他代理配置
        return (GenericService) proxy.create();
    }

    public boolean isValidCode(String code) {
        GenericService service = createGenericService();
        // 假设GenericExists包含isExists()方法返回boolean结果
        return service.exists(new CodeInput(code)).isExists();
    }

    // 提供setter方法设置genericServiceName
    public void setGenericServiceName(String genericServiceName) {
        this.genericServiceName = genericServiceName;
    }
}

编写TestNG测试用例

import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.*;

public class YourClassTest {
    @Mock
    private GenericService serviceMock;
    @Mock
    private GenericExists mockExistsResponse;

    private YourClass testInstance;

    @BeforeMethod
    public void setUp() {
        MockitoAnnotations.openMocks(this);
        // 创建子类重写服务创建方法,返回mock对象
        testInstance = new YourClass() {
            @Override
            protected GenericService createGenericService() {
                return serviceMock;
            }
        };
        testInstance.setGenericServiceName("http://example.com/GenericService");
    }

    @Test
    public void testIsValidCode_ReturnsTrue() {
        // 模拟exists方法的返回结果
        when(mockExistsResponse.isExists()).thenReturn(true);
        when(serviceMock.exists(any(CodeInput.class))).thenReturn(mockExistsResponse);

        boolean result = testInstance.isValidCode("TEST_CODE");
        assert result == true;
        // 验证mock方法被调用
        verify(serviceMock).exists(any(CodeInput.class));
    }
}

方案2:依赖注入(推荐,适合有DI框架的项目)

如果项目使用Spring等依赖注入框架,直接将GenericService作为依赖注入到类中,测试时注入mock对象即可:

重构原类

public class YourClass {
    private final GenericService genericService;

    // 构造注入GenericService
    public YourClass(GenericService genericService) {
        this.genericService = genericService;
    }

    public boolean isValidCode(String code) {
        return genericService.exists(new CodeInput(code)).isExists();
    }
}

编写TestNG测试用例

import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.*;

public class YourClassTest {
    @Mock
    private GenericService serviceMock;
    @Mock
    private GenericExists mockExistsResponse;

    private YourClass testInstance;

    @BeforeMethod
    public void setUp() {
        MockitoAnnotations.openMocks(this);
        testInstance = new YourClass(serviceMock);
    }

    @Test
    public void testIsValidCode_ReturnsTrue() {
        when(mockExistsResponse.isExists()).thenReturn(true);
        when(serviceMock.exists(any(CodeInput.class))).thenReturn(mockExistsResponse);

        boolean result = testInstance.isValidCode("TEST_CODE");
        assert result == true;
        verify(serviceMock).exists(any(CodeInput.class));
    }
}

方案3:PowerMock mock构造方法(不推荐,仅用于无法重构代码的场景)

如果无法修改原类,可以用PowerMock mockJaxWsProxyFactoryBean的构造和create方法,强制返回mock对象:

编写TestNG测试用例

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.*;

@PrepareForTest({YourClass.class, JaxWsProxyFactoryBean.class})
public class YourClassTest extends PowerMockTestCase {
    @Mock
    private GenericService serviceMock;
    @Mock
    private JaxWsProxyFactoryBean proxyMock;
    @Mock
    private GenericExists mockExistsResponse;

    private YourClass testInstance;

    @BeforeMethod
    public void setUp() throws Exception {
        MockitoAnnotations.openMocks(this);
        testInstance = new YourClass();
        testInstance.setGenericServiceName("http://example.com/GenericService");

        // mock JaxWsProxyFactoryBean的构造函数
        PowerMockito.whenNew(JaxWsProxyFactoryBean.class).withNoArguments().thenReturn(proxyMock);
        // mock create方法返回mock的GenericService
        when(proxyMock.create()).thenReturn(serviceMock);
    }

    @Test
    public void testIsValidCode_ReturnsTrue() {
        when(mockExistsResponse.isExists()).thenReturn(true);
        when(serviceMock.exists(any(CodeInput.class))).thenReturn(mockExistsResponse);

        boolean result = testInstance.isValidCode("TEST_CODE");
        assert result == true;
        verify(proxyMock).setServiceClass(GenericService.class);
        verify(serviceMock).exists(any(CodeInput.class));
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:34:58