Reputation: 2103
I'm writing an outbound HttpRequestExecutingMessageHandler
based service activator which sends a POST
request to the 3rd party REST API and gets a JSON in response. The 3rd party REST API accepts JSON object as payload. The relevant test methods are as follows:
@BeforeEach
public void setUp() {
server = MockRestServiceServer.createServer(restTemplateBuilder.additionalMessageConverters(
httpMessageConverter).build());
messagingTemplate = new MessagingTemplate();
defaultDestination = new QueueChannel(1);
}
and
@Test
void testOutboutSMSRequestHanlder() throws Exception {
SMSTaskRequest request = new SMSTaskRequest("1",
Arrays.asList(new SMSTask(1, "123456", "Test Message")));
SMSTaskResponse response = new SMSTaskResponse("200", "OK", "task-status",
Arrays.asList(new SMSTaskStatus("1", "0 OK")));
server.expect(requestTo("http://localhost/foo/bar"))
.andRespond(withSuccess(objectMapper.writeValueAsString(response), APPLICATION_JSON));
messagingTemplate.send(outboundSMSRequestChannel,
MessageBuilder.withPayload(request)
.setHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE).setReplyChannel(defaultDestination).build());
SMSTaskResponse smsTaskResponse = messagingTemplate
.receiveAndConvert(defaultDestination, SMSTaskResponse.class);
assertThat(smsTaskResponse).isEqualTo(response);
}
I get a 404 error for the external service request even after configuring my gateway as follows
@Component
public class OutboundSMSHandlerGateway {
@Autowired
private MappingJackson2HttpMessageConverter httpMessageConverter;
@Bean
public PublishSubscribeChannel outboundSMSRequestChannel() {
return new PublishSubscribeChannel();
}
@ServiceActivator(inputChannel = "outboundSMSRequestChannel")
@Bean
public HttpRequestExecutingMessageHandler handleGatewaySMSRequest() {
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://localhost/foo/bar");
handler.setHttpMethod(POST);
handler.setExpectReply(true);
handler.setMessageConverters(Arrays.asList(httpMessageConverter));
handler.setExpectedResponseType(SMSTaskResponse.class);
return handler;
}
}
The error stack trace is as follows
org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [http://localhost/foo/bar] in the [bean 'handleGatewaySMSRequest'; defined in: 'class path resource [com/thoughtscape/sms/OutboundSMSHandlerGateway.class]'; from source: 'org.springframework.core.type.classreading.SimpleMethodMetadata@19f9d595']; nested exception is org.springframework.web.client.HttpClientErrorException$NotFound: 404 Not Found: [<html>
<head>
<title>Valet - Not Found</title>
<style>
body {
font-family: monospace;
}
</style>
</head>
<body>
404 - Not Found
</body>
</html>
]
, failedMessage=GenericMessage [payload=SMSTaskRequest(type=send-sms, taskNum=1, smsTasks=[SMSTask(taskID=1, recipient=123456, messageContent=Test Message, flashSms=null, characterCodingSet=null, smsCodec=null, successReport=null, failureReport=null, enableSmsReport=null)]), headers={replyChannel=org.springframework.integration.channel.QueueChannel@38f502fc, id=43ed8efa-7aea-34bd-6884-1938ed65e9d3, Content-Type=application/json, timestamp=1602675489316}]
at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.exchange(HttpRequestExecutingMessageHandler.java:210)
at org.springframework.integration.http.outbound.AbstractHttpRequestExecutingMessageHandler.handleRequestMessage(AbstractHttpRequestExecutingMessageHandler.java:320)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:62)
at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:224)
at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:180)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:570)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:520)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at com.thoughtscape.sms.SmsServiceApplicationTests.testOutboutSMSRequestHanlder(SmsServiceApplicationTests.java:87)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: org.springframework.web.client.HttpClientErrorException$NotFound: 404 Not Found: [<html>
<head>
<title>Valet - Not Found</title>
<style>
body {
font-family: monospace;
}
</style>
</head>
<body>
404 - Not Found
</body>
</html>
]
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:113)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:184)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:125)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:782)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:695)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:593)
at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.exchange(HttpRequestExecutingMessageHandler.java:196)
... 76 more
Upvotes: 0
Views: 5043
Reputation: 121272
MockRestServiceServer returns 404 status instead of mocking external service response
Don't confuse yourself: there is full no interaction with your mock server at all. You just perform a real HTTP call.
Let's analyze your code!
server = MockRestServiceServer.createServer(restTemplateBuilder.additionalMessageConverters(
httpMessageConverter).build());
So, you try to mock some result of restTemplateBuilder
and you are done here: no any reference to the server neither to the RestTemplate
!
I get a 404 error for the external service request even after configuring my gateway as follows
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://localhost/foo/bar");
handler.setHttpMethod(POST);
handler.setExpectReply(true);
handler.setMessageConverters(Arrays.asList(httpMessageConverter));
handler.setExpectedResponseType(SMSTaskResponse.class);
return handler;
And what? Where is an interaction with the mock server? See docs on the matter: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html#spring-mvc-test-client
The very important phrase:
// Test code that uses the above RestTemplate ...
So, what you need to make it working properly is a RestTemplate
bean injected into that HttpRequestExecutingMessageHandler
. And the same RestTemplate
instance must be used from that MockRestServiceServer.createServer()
. Only this way your HTTP outbound gateway is going to interact with the mocked RestTemplate
which is going to pull answers from the mentioned mock server.
Otherwise the HttpRequestExecutingMessageHandler
creates its own internal RestTemplate
which knows nothing about mocking and is going to perform real request to the mentioned URL.
Upvotes: 1