Causes MockRestServiceServer response body's to be null in tests
Opened this issue · 2 comments
Hi,
This library works great for logging requests/ responses in dev/prod environments. Unfortunately, after installing this library and running my test suite, I got failures in all instances where I was mocking restTemplate
responses.
In my Kotlin JUnit tests
import org.springframework.test.web.client.MockRestServiceServer
private var server: MockRestServiceServer? = null
@Autowired
lateinit var restTemplate: RestTemplate
@BeforeEach
fun setUp() {
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build()
}
@Test
fun someTest(){
val resource: Path = Paths.get(javaClass.classLoader.getResource("mockResponses/someResource.json").toURI())
val resourceJson: String = Files.lines(resource).collect(Collectors.joining())
server!!.expect(once(), requestTo("https://example.com/someResource.json"))
.andExpect(method(HttpMethod.GET))
.andExpect(header("Authorization", "Basic $myAccessToken"))
.andRespond(MockRestResponseCreators.withSuccess(resourceJson, MediaType.APPLICATION_JSON))
}
// test something that ultimately invokes this stubbed endpoint
In these tests, I see the log lines for both the request and the response. The response logging actually shows the full json
content of my stubbed response (ie what I've read from the file system as a stored json file), but for whatever reason, this doesn't actually get returned anymore.
For now, I've removed the logging capability from being used in tests by having a test version of the rest client and regular version otherwise using profiles. I'd really like to be able to use this in tests without my tests breaking because seeing the JSON request is quite useful since matching the .content
in MockRestServiceServer
only gives feedback that there was an exact match or there wasn't without any more info.
Hi @mistahenry, thanks for raising this issue. I haven't tried spring-rest-template-logger with MockRestServiceServer
but I think this makes sense - the docs mention that it replaces the template's request factory:
In the preceding example,
MockRestServiceServer
(the central class for client-side REST tests) configures theRestTemplate
with a customClientHttpRequestFactory
that asserts actual requests against expectations and returns “stub” responses.
LoggingCustomizer
also replaces the template's request factory, by wrapping it in a buffering implementation:
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(restTemplate.getRequestFactory()));
This buffering decorator is required so that the response body stream can be read multiple times - first time for logging, second time for actual processing. I'd guess that MockRestServiceServer
is overwriting this buffering implementation which is why you're seeing a null response body.
The first step would be to create an IT for this MockRestServiceServer
use-case, much like LoggingCustomizerIT does for RestTemplate
. Would you like to give this a go?
I may be late to the party but I was facing the same issue although I did not use spring-rest-template-logger but instead my own logging interceptor.
As a workaround you can simply tell MockRestServiceServer to actually buffer the response bodies by setting the bufferContent
option in its builder, e.g.
final var mockServer = MockRestServiceServer.bindTo(restTemplate).bufferContent().build();
Pretty sure this should work here as well.
See also spring-projects/spring-framework#19258.