gpt4 book ai didi

java - 可以使用 Mockito 来模拟 org.jibx.runtime.BindingDirectory 吗?

转载 作者:行者123 更新时间:2023-12-02 00:16:21 25 4
gpt4 key购买 nike

我正在为 Java 应用程序编写单元测试,并且需要为可能引发的潜在 JiBX 异常编写测试。我正在测试的方法调用另一个类的方法,其中可能会引发 JiBX 异常。这是我正在测试的类(我们称之为 A 类):

@Inject
private CommonDAL commonDAL;

@Async
public Future<String> getTransactionalXXXAvailability(
List<XXXAvailRequestEntry> requestEntries, TravelWindow travelWindow) {
if (requestEntries.size() == 0)
return null;
XXXAvailRqAccessor requestAccessor = new XXXAvailRequestBuilder().buildRequest(requestEntries, travelWindow);
logger.info(requestAccessor.marshalRequest());
String responseAsXml = null;
try {
responseAsXml = getResponse(requestAccessor.getRequest());
} catch (JiBXException e) {
logger.error("Problem unmarshaling the XXX avail response: ", e);
}

logger.info(responseAsXml);
return new AsyncResult<String>(responseAsXml);
}

private String getResponse(OTAXXXAvailRQ request) throws JiBXException {
HbsiConnectionInfo connectionInfo = new HbsiConnectionInfo();
connectionInfo.useConnectionInfoFromContext();

HBSIXML4OTAWebserviceSoap hbsiSoap = getHbsiSoapService(connectionInfo);

InterfacePayload header = new InterfacePayload();
header.setChannelIdentifierId("XXXXXXXXX");
header.setVersion("2005B");
header.setInterface("HBSI XML 4 OTA");

ComponentInfo componentInfo = new ComponentInfo();
XXXAvailRqAccessor requestAccessor = new XXXAvailRqAccessor(request);
componentInfo.setId(requestAccessor.getFirstXXXCode());
componentInfo.setUser( connectionInfo.getUsername() );
componentInfo.setPwd( connectionInfo.getPassword() );
componentInfo.setComponentType(EComponentType.XXX);

Login login = new Login();
login.setComponentInfo(componentInfo);

Message body = new Message();
// todo: this needs to be unique for every request.
// todo: hook up to logging
body.setRequestId(UUID.randomUUID().toString());
body.setTransaction(ETransaction.XXX_AVAIL_RQ);

body.setXML(requestAccessor.marshalRequest());

return hbsiSoap.getSoapRequest(header, body, login);
}

HBSIXML4OTAWebserviceSoap getHbsiSoapService(HbsiConnectionInfo connectionInfo) {
HBSIXML4OTAWebservice ws = new HBSIXML4OTAWebservice( connectionInfo.getWsdlLocation() );

HBSIXML4OTAWebserviceSoap hbsiSoap = ws.getHBSIXML4OTAWebserviceSoap();
Map<String, Object> requestContext = ((BindingProvider)hbsiSoap).getRequestContext();
String readTimeout = commonDAL.getPropertyValue(new PropertyKey(Section.HBSI,
Property.HBSI_WS_READ_TIMEOUT));
requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT, Integer.parseInt(readTimeout));
String connectionTimeout = commonDAL.getPropertyValue(new PropertyKey(Section.HBSI,
Property.HBSI_WS_CONNECTION_TIMEOUT));
requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT, Integer.parseInt(connectionTimeout));
return hbsiSoap;
}

抛出错误的方法如下(来自另一个类,我们称其为B类):

public String marshalRequest() {
StringWriter requestAsXml = new StringWriter();

try {
IBindingFactory bindingFactory = BindingDirectory.getFactory(PROTECTEDCLASSNAME.class);
IMarshallingContext marshalingContext = bindingFactory.createMarshallingContext();
marshalingContext.setIndent(2);
marshalingContext.setOutput(requestAsXml);
marshalingContext.marshalDocument(request);

} catch (JiBXException e) {
logger.error("Problem marshaling PROTECTEDCLASSNAME.", e);
}

return requestAsXml.toString();
}

当“body.setXML(requestAccessor.marshalRequest());”时被调用时,测试会访问另一个类 (requestAccessor),并且它的方法 .marshalRequest 是应该抛出 JiBX 异常的地方。我正在编写的测试的目的是使该 A 类的单元测试覆盖率达到 100&,但被测系统至少由两个类组成,因为我无法模拟名为 requestAccessor 的 XXXAvailRqAccessor 对象。由于以下原因,我无法进行任何测试来产生此错误。

  • 名为 requestAccessor 的 XXXAvailRqAccessor 对象在我正在测试的方法中实例化,因此我无法使用模拟来引发异常。

  • 无法模拟传递给 .getResponse() 的 OTAXXXAvailRQ 参数,因为它是由 XXXAvailRqAccessor 的构建器创建的。

  • 我尝试监视 IBindingFactory,但没有成功。我在 B 类中创建了一个方法来实例化 IBindingFactory,以便我可以监视它,但这不起作用。

  • 我还尝试使用 PowerMock 在实例化时返回模拟 XXXAvailRqAccessor,但是当我尝试为 .getRequest 模拟 JiBXExceptioin 时,Mockito 说“检查的异常对此方法无效”。如果我不能让 Mockito 抛出这个错误,我不知道是否可以操纵关联的对象来抛出它。

最佳答案

其实不是,或者至少我不知道这样的方式。如果你真的想这样做(我反对),你可以在该类中创建一个像这样的方法:

IBindingFactory getBindingFactory() {
return BindingDirectory.getFactory(PROTECTEDCLASSNAME.class);
}

并替换这一行:

IBindingFactory bindingFactory = BindingDirectory.getFactory(PROTECTEDCLASSNAME.class);

与:

IBindingFactory bindingFactory = getBindingFactory();

然后你可以spy()(如果你不熟悉的话,你可以阅读文档中的Mockito.spy())这个对象并让这个方法返回一个模拟。从那时起,一切就一帆风顺了。

不建议使用这种方法,因为:

  1. 您正在创建一种新方法(无用的方法)只是为了测试
  2. 该方法必须对测试可见,因此您不能将其标记为私有(private)...
  3. 总的来说,我不太喜欢 spy

问题仍然是:如何正确测试此类案例。在大多数情况下,我会尝试尽可能多地重构,有时这会有所帮助。而在其他情况下......好吧,我仍然没有想出更好的解决方案。

关于java - 可以使用 Mockito 来模拟 org.jibx.runtime.BindingDirectory 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11846578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com