首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用HttpRequestExecutingMessageHandler测试MockRestServiceServer

用HttpRequestExecutingMessageHandler测试MockRestServiceServer
EN

Stack Overflow用户
提问于 2016-12-30 00:20:54
回答 1查看 4K关注 0票数 4

我正在开发一个使用Spring的应用程序,它使用HttpRequestExecutingMessageHandler类定期向REST服务发出后端请求。我想在测试中模拟REST服务器,而不是构建一个模拟服务器,我更愿意使用MockRestServiceServer来实现这一点。然而,MockRestServiceServer似乎并没有拦截RestTemplate调用,相反,它们正在通过( http://example.com/)和提高java.net.ConnectException: Connection refused。有没有办法强迫HttpRequestExecutingMessageHandler调用MockRestServiceServer,还是应该重新考虑这种测试策略?

应用程序的配置:

代码语言:javascript
复制
@Configuration
public class RestClientTestApplicationConfig {
    @Bean
    @Qualifier("httpRequestChannel")
    public MessageChannel httpRequestChannel() { return new QueueChannel(); }

    @Bean
    @Qualifier("httpReplyChannel")
    public MessageChannel httpReplyChannel() { return new QueueChannel(); }

    @Bean
    public RestTemplate restTemplate() { return new RestTemplate(); }

    @Bean
    @InboundChannelAdapter(value="httpRequestChannel", poller=@Poller(fixedDelay = "1000"))
    public MessageSource<String> httpRequestTrigger() { return new ExpressionEvaluatingMessageSource<>(new LiteralExpression(""), String.class); }

    @Bean
    @ServiceActivator(inputChannel="httpRequestChannel", poller=@Poller(fixedDelay = "1000"))
    public MessageHandler messageHandler(
        RestTemplate restTemplate,
        @Qualifier("httpReplyChannel") MessageChannel messageChannel,
        @Value("${url}") String url
    ) {
        HttpRequestExecutingMessageHandler messageHandler = new HttpRequestExecutingMessageHandler(url, restTemplate);
        messageHandler.setOutputChannel(messageChannel);
        return messageHandler;
    }
} 

(urlapplication-test.properties中被定义为测试中的http://example.com,否则为真正的http://example.com)

测试:

代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RestClientIntegrationTest {
    @Autowired
    private RestTemplate restTemplate;

    private MockRestServiceServer mockServer;

    @Before
    public void setup() {
        mockServer = MockRestServiceServer.createServer(restTemplate);
    }

    @Test
    public void makesBackendRequest() {
        mockServer.expect(ExpectedCount.once(), MockRestRequestMatchers.requestTo("http://example.com/"))
            .andExpect(MockRestRequestMatchers.method(HttpMethod.GET));

        mockServer.verify();
    }
}

测试结果:

代码语言:javascript
复制
2016-12-29 16:14:36.902 ERROR 16665 --- [ask-scheduler-2] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [http://example.com]; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://example.com": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
    at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.handleRequestMessage(HttpRequestExecutingMessageHandler.java:409)

java.lang.AssertionError: Further request(s) expected leaving 1 unsatisfied expectation(s).
0 request(s) executed.
    at org.springframework.test.web.client.AbstractRequestExpectationManager.verify(AbstractRequestExpectationManager.java:103)
    at org.springframework.test.web.client.MockRestServiceServer.verify(MockRestServiceServer.java:117)
    at com.restclienttest.RestClientIntegrationTest.makesBackendRequest(RestClientIntegrationTest.java:35)

UPDATE按照Artem的评论修改了测试代码如下:

代码语言:javascript
复制
    mockServer.expect(ExpectedCount.once(), MockRestRequestMatchers.requestTo("http://example.com/"))
        .andExpect(MockRestRequestMatchers.method(HttpMethod.GET))
        .andRespond(MockRestResponseCreators.withSuccess("example reply", MediaType.TEXT_PLAIN));

    Message<?> message = httpReplyChannel.receive(1001);
    assertNotNull(message);
    assertThat(((ResponseEntity<String>) message.getPayload()).getBody(), is("example reply"));

但是,获取ConnectExceptionMockRestServiceServer发送的示例答复似乎仍未通过,因为ResponseEntity的主体为null。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-30 04:02:23

我觉得你在这里很好。只有您忽略了应用程序是异步这一事实的问题。@InboundChannelAdapter定期向QueueChannel发送消息,等等。但是它是在计票者的线程中这样做的,而不是在等待验证的那个线程中。

作为一个修正,我认为您应该等待httpReplyChannel中通过其.receive(10000)方法的回复。然后再打电话给mockServer.verify()

更新

嗯。我想我们已经为你准备了一个测试用例:

代码语言:javascript
复制
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>

<int-http:outbound-gateway url="/testApps/httpMethod"
                           request-channel="requestChannel"
                           reply-channel="replyChannel"
                           rest-template="restTemplate"
                           expected-response-type="java.lang.String"
                           http-method-expression="payload"/>

<int:channel id="replyChannel">
    <int:queue/>
</int:channel>
代码语言:javascript
复制
@Autowired
private RestTemplate restTemplate;

private MockRestServiceServer mockServer;

@Before
public void setup() {
    this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
}

@Test
public void testDefaultMethod() throws Exception {
    this.mockServer.expect(requestTo("/testApps/httpMethod"))
            .andExpect(method(HttpMethod.POST))
            .andRespond(withSuccess(HttpMethod.POST.name(), MediaType.TEXT_PLAIN));

    this.defaultChannel.send(new GenericMessage<String>("Hello"));
    Message<?> message = this.replyChannel.receive(5000);
    assertNotNull(message);
    assertEquals("POST", message.getPayload());

    this.mockServer.verify();
}

https://github.com/spring-projects/spring-integration/blob/master/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayWithMethodExpressionTests.java

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41389013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档