如何使用Mockito测试SOAP消息



我对Mockito相当陌生,我想我会尝试使用它来测试SOAP处理程序。然而,事实证明,这比我预期/期望的要痛苦得多。

我希望验证我的处理程序是否能够提取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));
    }
}

正如我所说,它是有效的,但它看起来像是一个非常丑陋/沉重的解决方案。

有没有什么办法让这件事更简单/更干净?

谢谢!

Eric

    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;

这里有点晚了,但我更喜欢生成一个代理mockito mock的工作Endpoint。这让我可以测试整个堆栈,包括拦截器和/或处理程序,这对您的用例应该很有帮助。

我提出了一个简单的JUnit规则,它在一定程度上简化了这里的事情。生成的测试用例应该是小而干净的。我建议直接从XML文件加载测试XML响应,因为这样维护起来更快、更简单。

不要嘲笑这样的事情。

听代码。。。它告诉你这不是正确的做法。

相反,只需创建一个(真实的)消息,其中包含一些已知的数据,并断言您的代码对它做了正确的处理

例如

MessageIdExtractor提取器=新MessageIdExtrator();//<-你正在测试

字符串expectedMessageId="xxxxxx";

消息m=新SOAPMessage().setMessageId(expectedMessageId);

assertThat(extracter.extractIdFrom(m),equalTo(expectedMessageId));

相关内容

  • 没有找到相关文章

最新更新