我正在为我的Java应用程序编写单元测试,我需要为可能引发的潜在JiBX异常编写一个测试。我正在测试的方法调用另一个类的方法,其中JiBX异常可能会被抛出。这是我测试的类(姑且称之为A类):可以使用Mockito来模拟org.jibx.runtime.BindingDirectory吗?
@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,但是当我试图模拟JiBXExceptioin for .getRequest时,Mockito说“检查异常对于此方法无效”。如果我不能让Mockito抛出这个错误,我不知道是否可以操纵关联的对象来抛出它。
其实这是一个很好的解决方案。创建仅用于测试的新方法没有任何问题。最好有一个很好的可测试的类,而不是少一个方法。新方法必须是包私有的,这非常合适。这种类型的问题是间谍少数真正的好用途之一。还有另一种方法可以做到这一点,您可能更喜欢 - 我会在几个小时内发布答案(如果我记得的话)。 – 2012-08-08 02:23:48