restdocs-wiremock
restdocs-wiremock copied to clipboard
Stubs loaded from absolute path
We're trying to integrate wiremock-spring-boot-starter in our project using the default configuration (adding dependency + @WireMockTest
). We have our response body files under src/test/resources/__files
, which is the default location for Wiremock. When we run our tests we get this exception:
java.lang.RuntimeException: java.io.FileNotFoundException: /__files/product-catalog-response.json (No such file or directory)
at com.github.tomakehurst.wiremock.common.BinaryFile.readContents(BinaryFile.java:38) ~[wiremock-standalone-2.10.1.jar:na]
at com.github.tomakehurst.wiremock.http.StubResponseRenderer.renderDirectly(StubResponseRenderer.java:95) ~[wiremock-standalone-2.10.1.jar:na]
at com.github.tomakehurst.wiremock.http.StubResponseRenderer.buildResponse(StubResponseRenderer.java:65) ~[wiremock-standalone-2.10.1.jar:na]
at com.github.tomakehurst.wiremock.http.StubResponseRenderer.render(StubResponseRenderer.java:54) ~[wiremock-standalone-2.10.1.jar:na]
at com.github.tomakehurst.wiremock.http.AbstractRequestHandler.handle(AbstractRequestHandler.java:47) ~[wiremock-standalone-2.10.1.jar:na]
at com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet.service(WireMockHandlerDispatchingServlet.java:102) ~[wiremock-standalone-2.10.1.jar:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at wiremock.org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) ~[wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) ~[wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83) ~[wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:301) ~[wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.Server.handle(Server.java:499) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [wiremock-standalone-2.10.1.jar:na]
at wiremock.org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [wiremock-standalone-2.10.1.jar:na]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
It looks like Wiremock is trying to find the files using an absolute path, instead of going to the classpath. In fact, if we create a __files
in the root directory of our computer with the same contents the tests work fine.
We haven't been able to figure out how to configure this properly to load the contents from the classpath, is there any way to do it?
You can use the stubPath
attribute of WireMockTest
to tell it where to look for the wiremock stubs. This folder is resolved as a classpath resource.
So in your case you could use.
@WireMockTest(stubPath = "__files")
Thanks for your response. We actually tried using what you propose, and it doesn't seem to work. We're getting this error:
wiremock.com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "productBandOutput" (class com.github.tomakehurst.wiremock.stubbing.StubMapping), not marked as ignorable (11 known properties: "response", "requiredScenarioState", "priority", "persistent", "id", "postServeActions", "request", "newScenarioState", "name", "uuid", "scenarioName"])
at [Source: {
"productBandOutput": [
{
//...
]
}
]
}; line: 2, column: 25] (through reference chain: com.github.tomakehurst.wiremock.stubbing.StubMapping["productBandOutput"])
at wiremock.com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62)
at wiremock.com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:834)
at wiremock.com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1093)
at wiremock.com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1478)
at wiremock.com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1456)
at wiremock.com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:282)
at wiremock.com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140)
at wiremock.com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814)
at wiremock.com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2858)
at com.github.tomakehurst.wiremock.common.Json.read(Json.java:48)
at com.github.tomakehurst.wiremock.stubbing.StubMapping.buildFrom(StubMapping.java:66)
at com.github.tomakehurst.wiremock.standalone.JsonFileMappingsSource.loadMappingsInto(JsonFileMappingsSource.java:82)
at com.github.tomakehurst.wiremock.core.WireMockApp.loadMappingsUsing(WireMockApp.java:154)
at com.github.tomakehurst.wiremock.WireMockServer.loadMappingsUsing(WireMockServer.java:121)
at com.epages.wiremock.starter.WireMockListener.beforeTestMethod(WireMockListener.java:76)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:269)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
It looks like Wiremock is trying to load our response body file as a stub mapping using the JSON API when in reality we're using .withBodyFile("product-catalog-response.json")
in the wiremock server configuration. If we remove the wiremock starter and use just vanilla wiremock it works fine as we have our files in the default location (__files
).
Does the folder contain stub files and response/request body files? It looks like WireMock is parsing a body file as a stub file and fails deserializing it.
In all the cases I tested the body was part of the stub file (inline body). Can you share a sample project to share so I could have a closer look myself?
When recording stub with external body files I have seen that WireMock stores the stubs in a mappings
directory and the body files to __files
.
So you could try to have
-
src/test/resources/stubs/mappings
with the stub files -
src/test/resources/stubs/__files
with the body files
Then use WireMockTest
like this:
@WireMockTest(stubPath = "stubs")