有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java可以使用Mockito来模拟组织。吉布斯。运行时。绑定目录?

我正在为我的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;
}

抛出错误的方法如下(从另一个类,我们称之为class 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.marshallrequest());”调用,测试访问另一个类(requestAccessor)及其方法。marshalRequest是应该抛出JiBX异常的地方。我写这些测试的目的是让A级的单元测试覆盖率达到100&;,但测试中的系统至少由两个类组成,因为我无法模拟名为requestAccessor的xxxavairqAccessor对象。由于以下原因,我无法进行任何测试来产生此错误

  • 名为requestAccessor的xxxavairqAccessor对象在我正在测试的方法中被实例化,因此我不能使用模拟抛出异常

  • Otaxxxavairq参数传递给。getResponse()无法模拟,因为它是由xxxavairqAccessor的生成器创建的

  • 我试着监视宜宾工厂,但没用。我在类B中创建了一个方法,该方法将实例化一个IBindingFactory,这样我就可以监视它,但这不起作用

  • 我还尝试在实例化时使用PowerMock返回一个模拟的xxxavairqAccessor,但是当我试图模拟一个JiBXExceptioin时。getRequest,Mockito说“选中的异常对于该方法无效”。如果我不能让Mockito抛出这个错误,我不知道是否有可能操纵相关的对象来抛出它


共 (1) 个答案

  1. # 1 楼答案

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

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

    替换这一行:

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

    与:

    IBindingFactory bindingFactory = getBindingFactory();
    

    然后可以spy()(如果不熟悉,可以阅读文档中的Mockito.spy())这个对象,并使这个方法返回一个mock。从那时起,一切都很顺利

    不过,这种方法并不可取,因为:

    1. 你正在创建一个新方法(一个无用的方法),只是为了测试
    2. 所述方法必须在测试时可见,因此您不能将其标记为私有
    3. 我一般不太喜欢间谍

    问题依然存在:如何正确地测试此类案例。在大多数情况下,我会尽可能多地重构,有时会有所帮助。在其他情况下。。。我还是没有想出更好的解决办法