我对Mockito很新,并且认为我会尝试使用它来测试SOAP Handler。然而,这比我预期/期望的更痛苦。
我希望验证我的处理程序能够在SOAPMessage的标头中提取messageID。但是,从处理程序,到达标题的唯一方法是通过context / message / part / envelope / header。使用Mockito,我的解决方案是模拟我的SOAPMessage,意味着创建每个单独的对象,并对方法进行存根。
我只能想象有一种更简单/更清洁的方法来实现这一目标:
@RunWith(MockitoJUnitRunner.class)
public class UUIDHandlerTest {
@Mock private SOAPMessage message;
@Mock private SOAPEnvelope envelope;
@Mock private SOAPHeader header;
@Mock private SOAPPart part;
@Mock
private SOAPMessageContext context;
@Before
public void setup() throws SOAPException{
when( context.getMessage()).thenReturn(message);
when( message.getSOAPPart()).thenReturn(part);
when( part.getEnvelope()).thenReturn(envelope);
when( envelope.getHeader()).thenReturn(header);
}
@Test
public void testHandleInboundMessage() {
when( context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).thenReturn(false);
when(header.getElementsByTagName(anyString())).thenAnswer(new Answer<NodeList>() {
/* (non-Javadoc)
* @see org.mockito.stubbing.Answer#answer(org.mockito.invocation.InvocationOnMock)
*/
@Override
public NodeList answer(InvocationOnMock invocation) throws Throwable {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(new String("<wsa:MessageID>messageId</wsa:MessageID>").getBytes()));
// TODO Auto-generated method stub
return doc.getElementsByTagName("wsa:MessageID");
}
});
// call the test class
new UUIDHandler().handleMessage(context);
// check the MDC value
assertEquals("messageId", MDC.get(LoggerConstants.DC_PROPERTY_MESSAGE_ID));
}
}
就像我说的,它有效,但它看起来像一个非常丑陋/重量级的解决方案。
有没有这样做更容易/更清洁?
谢谢!
埃里克
答案 0 :(得分:4)
SOAPMessageContext context =
mock(SOAPMessageContext.class, RETURNS_DEEP_STUBS);
when(context.getMessage().getSOAPPart().getEnvelope().
getHeader().getElementsByTagName(anyString())).
then(...);
还请注意mockito文档中使用深层存根的注意事项。 http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#RETURNS_DEEP_STUBS
注释风格:
@Mock(answer = Answers.RETURNS_DEEP_STUBS) SOAPMessageContext context;
答案 1 :(得分:1)
这里有点晚了,但我更喜欢产生一个代理mockito模拟的工作端点。这让我可以测试整个堆栈,包括拦截器和/或处理程序,这应该对你的用例有所帮助。
我提出了一个简单的JUnit规则,它简化了一些事情here。由此产生的测试用例应该小而干净。我建议直接从XML文件加载测试XML响应,因为这样更快,更易于维护。
答案 2 :(得分:-1)
不要嘲笑这样的事情。
听取代码......它告诉你这不是正确的方法。
相反,只需创建一个(真实的)消息,其中包含一些已知数据,并声明您的代码使用它做了正确的事情。
e.g。
MessageIdExtractor extractor = new MessageIdExtractor(); //&lt; - 您正在测试的课程
String expectedMessageId =“xxxxxx”;
消息m = new SOAPMessage()。setMessageId(expectedMessageId);
断言(extractor.extractIdFrom(m),equalTo(expectedMessageId));