在 Mockito 中模拟使用强制转换的对象

问题描述 投票:0回答:1

我正在开发一个 Java 项目,我需要使用 testng 为一个具有类似于以下方法的类编写单元测试:

public boolean isValidCode(String code) {
    GenericService service = null;
    JaxWsProxyFactoryBean proxy = new JaxWsProxyFactoryBean();
    proxy.setServiceClass(GenericService.class);
    proxy.setServiceName(new QName(this.genericServiceName));
    // More proxy configurations
    service = (GenericService) proxy.create();
    return service.exists(new CodeInput(code));
}

isValidCode 方法从服务接口 GenericService 调用“exists”方法。 GenericService中的exists方法负责检查代码是否存在。 我希望能够模拟创建的“服务”对象,特别是模拟“存在”方法。但是,我很难模拟这个对象,因为它是一个被转换为 GenericService 对象的 JaxWsProxyFactoryBean 对象。

这是 GenericService 的接口:

@WebService(name = "GenericService", targetNamespace = "http://example.com/GenericService")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
@XmlSeeAlso({
    ObjectFactory.class
})
public interface GenericService {

    @WebMethod(operationName = "GenericExists", action = "http://example.com/GenericService/GenericExists")
    @WebResult(name = "GenericExistsResponse", targetNamespace = "http://example.com/GenericService", partName = "response")
    public GenericExists exists(
        @WebParam(name = "GenericExistsRequest", targetNamespace = "http://example.com/GenericService", partName = "CodeInput")
        CodeInput codeInput);
}

我尝试如下模拟 GenericService 接口:

GenericService serviceMock = mock(GenericService.class)
when(serviceMock.exists(any(CodeInput.class))).thenReturn(true);

但是,这似乎不起作用,因为当我在测试中执行 isValidCode 时,它仍然调用实际的 WebMethod“存在”。我不确定这是否是因为 JaxWsProxyBeanFactory 对象的转换所致。

java unit-testing mocking mockito testng
1个回答
0
投票

首先,使用

mock(GenericService.class)
创建的模拟默认情况下不可用。 它将创建一个虚拟对象,您需要将其传递给正在测试的类才能使用它。

在您的特定用例中,您希望在调用

serviceMock
时返回您的
JaxWsProxyFactoryBean#proxy
。由于您的
JaxWsProxyFactoryBean
也在测试期间创建,因此您可以在通过
mockConstruction
创建对象期间将其替换为模拟。在
mockConstruction
中,您可以通过在调用时返回
proxy
来为您的
serviceMock
方法赋予新行为。

// create your mock object as normal
GenericService serviceMock = mock(GenericService.class);
when(serviceMock.exists(any(CodeInput.class))).thenReturn(true);

// change the construction of your JaxWsProxyFactoryBean
try (MockedConstruction<JaxWsProxyFactoryBean> mockJaxWsProxyFactoryBean = mockConstruction(JaxWsProxyFactoryBean.class, (mock, context) -> {
    // return your created serviceMock when the create method is called
    when(mock.create()).thenReturn(serviceMock);
})) {
    // do your asserts
    Assertions.assertTrue(myObject.isValidCode("foo"));

}
© www.soinside.com 2019 - 2024. All rights reserved.