Я работаю над приложением Spring Integration, которое использует класс HttpRequestExecutingMessageHandler
, чтобы делать запросы на бэкэнд службе REST через равные промежутки времени. Я хотел бы издеваться над сервером REST при тестировании, а вместо того, чтобы строить макетный сервер, я бы предпочел использовать MockRestServiceServer
для этого. Однако MockRestServiceServer
, кажется, не перехватывает RestTemplate
звонки, а вместо этого они проходят (до http://example.com/
) и поднимают java.net.ConnectException: Connection refused
. Есть ли способ заставить HttpRequestExecutingMessageHandler
позвонить по телефону MockRestServiceServer
или мне следует пересмотреть эту стратегию тестирования?Тестирование HttpRequestExecutingMessageHandler с использованием MockRestServiceServer
Конфигурация для приложения:
@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
- null.
Использование асинхр сейчас, но все еще получаю 'ConnectException'. Кажется, что сообщение доходит до 'httpReplyChannel', но тело сообщения кажется отсутствующим. –
Я думаю, что вы должны сделать свой '@ InboundChannelAdapter' как' autoStartup = "false" и 'start()' он вручную в тесте после построения mockServer.expect() '. Для этого вам следует добавить компонент SourcePollingChannelAdapter. –
Отлично, это работает отлично! Есть ли способ внедрить свойство 'autoStartup' на основе свойств, так что для профилей dev/prod' autoStartup = "true" ', но для test' autoStartup = "false" '? –