Reputation: 3678
I wonder if anyone can help - this has been driving me crazy for days!
I have a fairly simple Spring Integration file that I'd like to unit test. The SI uses an http outbound gateway, and I specifically want to unit test rather than integration test - I do not want to provide a mock http server using something like Spark or MockRestServiceServer.
My SI config looks like this:
<int:channel id="modifiedAttractionChannel" datatype="u.o.n.p.i.a.s.AttractionUuid">
<int:interceptors>
<int:wire-tap channel="attractionModifiedChannelLogging"/>
</int:interceptors>
</int:channel>
<int-http:outbound-gateway
id="serviceGateway"
request-channel="modifiedAttractionChannel"
url="/attractions/{uuid}"
http-method="GET"
expected-response-type="u.o.n.p.i.a.v.m.Attraction"
charset="UTF-8"
reply-timeout="${vader.reply.timeout}"
request-factory="clientHttpRequestFactory"
reply-channel="vaderAttractionChannel">
<int-http:uri-variable name="uuid" expression="headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value" />
</int-http:outbound-gateway>
<int:channel id="attractionChannel" datatype="u.o.n.p.i.a.v.m.Attraction">
<int:interceptors>
<int:wire-tap channel="vaderAttractionChannelLogging"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter
id="attractionModifiedChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
<int:logging-channel-adapter
id="vaderAttractionChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
I have written a unit test that wires up a basic spring context and am able to get the modifiedAttractionChannel
and send
an appropriately built Message
with an AttractionUuid
payload and header value.
My unit test can assert that the log message written to attractionModifiedChannelLogging
is as I expect it (I created the AttractionUuid
and Message
, so I know the payload and header values)
What I now need to do is assert the value written to the vaderAttractionChannelLogging
wiretap. IE. I need to assert a message with a given header value - no problem, I created the header value as part of the test - but also the payload.
In this case the payload is the output of the outbound gateway. Given that this is a unit test and I don't want any dependency on anything else, I have provided a mock ClientHttpRequestFactory
which in turn provides a mock ClientHttpResponse
via a mock ClientHttpRequest
This works great in that I can control the response body that the outbound gateway would otherwise receive. However, the RestTemplate
calls its HttpRequestExecutingMessageHandler
in order to convert the response body into an object via the MessageConverter
s
Whilst this works in respect of the execution of the SI flow, it means the instance of Attraction
that is on the reply-channel vaderAttractionChannel
is not in control of the test; and therefore I cannot make any assertions about it in respect of what gets logged on the vaderAttractionChannelLogging
wiretap.
I think one way of addressing this is to be able to wire in a mock or stub MessageConvertor
instead of the standard set that returns a fixed Attraction
instance. But I can't for the life of me work out how to!
Note: The scenario above is a much simplified version of what I'm actually trying to do. I'm not really trying to write unit tests around logged values! I need to test the overall flow of my SI, and being able to control the instance of the Attraction
that the outbound gateway returns is very much key to that.
Any help with this would be very much appreciated;
Cheers
Nathan
Upvotes: 2
Views: 1461
Reputation: 174729
It's not clear what your issue is; "...the RestTemplate calls its HttpRequestExecutingMessageHandler..." - it's actually the other way around. If you really want to unit test the flow, you should provide a normal result from the mock that will be converted by the standard converters. If you really want to mock the conversion too, use the message-converters attribute.
Upvotes: 1