2014-05-07 41 views
2

我試圖單元測試它試圖隱藏所有的Web服務實現細節一個Web服務包裝類。它是從腳本平臺調用的,所以所有接口都是簡單的字符串或整數。該類提供了一種靜態初始化方法,該方法使用主機名和端口號,並使用此方法創建一個私有靜態Apache CXF IRemote端口實例(由CXF wsdl2java生成)。隨後調用靜態業務方法委託給端口實例。JMockit - 模擬CXF Web服務端口對象

如何使用JMockit嘲笑CXF端口存根當單元測試靜態包裝類? web服務的

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(); 
    } 
} 

實例行爲會是這樣,如果我通過了值「OK」,那麼它會返回一個成功的消息,但如果我用的值稱爲「DUPLICATE」,那麼web服務將拋出一個MyBusinessException_Exception。

我想我已經成功地嘲笑_port對象,但讓我懷疑我的期望不正確定義「BusinessThing」對象的業務呼叫總是返回一個空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); 
} 
+0

我覺得我到達那裏。我想,我的期望是不是在傳遞的請求對象的具體實例匹配。它看起來像我需要爲我的BusinessMethodRequest對象的自定義匹配其只關心request.getThing()的getValue() 如果能用內置的匹配器完成,請大聲呼喊。 –

回答

2

似乎工作如下。

加在我的期望定製匹配器類我BusinessMethodRequest

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); 
} 

模擬對象現在使用正確的參數識別業務方法調用,並返回預期的響應對象。