JMockit - объект, макет порта в CXF веб-сервиса


Я пытаюсь провести модульный тест класса-оболочки webservice, который пытается скрыть все детали реализации webservice. Он вызывается из скриптовой платформы, поэтому все интерфейсы являются простыми строками или целыми числами. Класс предоставляет статический метод инициализации, который принимает имя хоста и номер порта и использует его для создания частного статического экземпляра порта Apache CXF IRemote (генерируемого из CXF wsdl2java). Последующие вызовы статического бизнес-метода делегируют экземпляр порта.

Как могу ли я использовать JMockit для макетирования заглушки порта CXF при модульном тестировании класса static wrapper?

public class WebServiceWrapper {

private static final QName SERVICE_NAME = new QName("http://www.gwl.org/example/service", 
        "ExampleService");
private static IRemoteExample _port = null;

public static final String initialise(String url) {
    if(_port != null) return STATUS_SUCCESS;
    try {
        URL wsdlURL = new URL(url);

        ExampleService svc = new ExampleService(wsdlURL, SERVICE_NAME);
        _port = svc.getIRemoteExamplePort();

        BindingProvider bp = (BindingProvider)_port;
        Map<String, Object> context = bp.getRequestContext();
        context.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);

        return STATUS_SUCCESS;
    }
    catch(MalformedURLException ex) {
        return STATUS_ERROR_PREFIX + ex.getMessage();
    }
    catch(WebServiceException ex) {
        return STATUS_ERROR_PREFIX + ex.getMessage();
    }
}

public static final String businessMethod(String arg) {
    if(_port == null) {
        return STATUS_ERROR_PREFIX + "Attempted to call businessMethod before connection is initialised. Pease call initialise first.";
    }

    try {
        BusinessMethodRequest request = new BusinessMethodRequest ();
        BusinessThing thing = new BusinessThing();
        thing.setValue(arg);
        request.setThing(thing);
        BusinessMethodResponse response = _port.businessMethod(request);
        String result = response.getResult();       
        if(result == null) {
            return STATUS_ERROR_PREFIX + "Null returned!";
        }
        return STATUS_SUCCESS;
    }
    catch(MyBusinessException_Exception ex) {
        return STATUS_ERROR_PREFIX + ex.getFaultInfo().getReason();
    }
    catch(WebServiceException ex) {
        return STATUS_ERROR_PREFIX + ex.getMessage();
    }
}

Пример поведения webservice был бы, если я передаю значение "OK", то он возвращает сообщение об успехе, но если я вызываю со значением" DUPLICATE", то webservice бросит MyBusinessException_Exception.

Я думаю, что мне удалось поиздеваться над объектом _port, но бизнес-вызов всегда возвращает объект null Response, поэтому я подозреваю, что мои ожидания не определяют Объект "бизнес-управление" правильно. Мой тестовый метод до сих пор.

    @Test
public void testBusinessMethod(@Mocked final IRemoteExample port) {

    new NonStrictExpectations() {
        @Capturing IRemoteExample port2;
        {
            BusinessThing thing = new BusinessThing();
            thing.setValue("OK");
            BusinessMethodRequest req = new BusinessMeothdRequest();
            req.setThing(thing);

            BusinessMethodResponse resp = new BusinessMethodResponse ();
            resp.setResult("SUCCESS");

            try {
                port.businessMethod(req);
                returns(resp);
            }
            catch(MyBusinessException_Exception ex) {
                returns(null);
            }

            Deencapsulation.setField(WebServiceWrapper.class, "_port", port);
        }
    };

    String actual = WebServiceWrapper.businessMethod("OK");
    assertEquals(WebServiceWrapper.STATUS_SUCCESS, actual);
}
1 2

1 ответ:

, по-видимому, работает следующим образом.

Добавлен пользовательский класс сопоставления для моего Businessmethod Request

    class BusinessMethodRequestMatcher extends TypeSafeMatcher<BusinessMethodRequest> {

    private final BusinessMethodRequestexpected;

    public BusinessMethodRequestMatcher(BusinessMethodRequest expected) {
        this.expected. = expected;
    }

    @Override
    public boolean matchesSafely(BusinessMethodRequest actual) {
        // could improve with null checks
        return expected.getThing().getValue().equals(actual.getThing().getValue());
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(expected == null ? null : expected.toString());
    }
}

Тогда используйте "С" в моем ожидании.

    try {
    port.createResource(with(req, new BusinessMethodRequestMatcher(req)));
    returns(resp);
}

Макет объекта теперь распознает вызов бизнес-метода с правильным параметром и возвращает ожидаемый объект ответа.