我正在使用Spring Integration使用HttpRequestExecutingMessageHandler
類以定期向REST服務發出後端請求。我想在測試中嘲笑REST服務器,而不是構建模擬服務器,我寧願使用MockRestServiceServer
來執行此操作。但是,MockRestServiceServer
似乎不會攔截RestTemplate
調用,而是他們正在經歷(至http://example.com/
)並提高java.net.ConnectException: Connection refused
。有沒有辦法迫使HttpRequestExecutingMessageHandler
致電MockRestServiceServer
,或者我應該重新考慮這個測試策略嗎?爲應用程序使用MockRestServiceServer測試HttpRequestExecutingMessageHandler
配置:
@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", [email protected](fixedDelay = "1000"))
public MessageSource<String> httpRequestTrigger() { return new ExpressionEvaluatingMessageSource<>(new LiteralExpression(""), String.class); }
@Bean
@ServiceActivator(inputChannel="httpRequestChannel", [email protected](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;
}
}
(url
在application-test.properties
定義爲在測試http://example.com
否則真實URL)
測試:
@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();
}
}
測試結果:
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 改編測試代碼如下,按阿爾喬姆比蘭的評論:
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"));
仍然得到ConnectException
和答覆由MockRestServiceServer
發送的例子似乎並沒有獲得通過,因爲身體的ResponseEntity
爲空。
現在使用異步,但仍然得到'ConnectException'。該消息似乎通過「httpReplyChannel」,但消息的正文似乎丟失。 –
我認爲在構建mockServer.expect()之後,您必須在測試中手動將'@ InboundChannelAdapter'設置爲'autoStartup =「false」'和'start()'。爲此目的,你應該注入'SourcePollingChannelAdapter' bean。 –
太棒了,這工作正常!有沒有一種方法可以根據屬性注入'autoStartup'屬性,所以對於dev/prod配置文件'autoStartup =「true」'但對於測試'autoStartup =「false」'? –