Closed virgium03 closed 10 months ago
Jackson jackson-datatype-jdk8
and jackson-datatype-jsr310
are transitive dependencies from spring-boot-starter-json
.
AFAIR the best way would be to pass the web application context via RestAssuredMockMvc.webAppContextSetup
. That way things should be resolved from application context instead of passing them manually
AFAIR the best way would be to pass the web application context via
RestAssuredMockMvc.webAppContextSetup
. That way things should be resolved from application context instead of passing them manually
In the end, i simplified the base class like this:
@WebMvcTest
@TestPropertySource("/application-test.properties")
@Import(xxx.class)
public class BaseContractTestClass {
@Autowired
private MockMvc mockMvc;
@BeforeEach
public void setup() {
RestAssuredMockMvc.mockMvc(mockMvc);
}
}
But that was not the issue that I was referring to.
The problem is in the JSON stubs which are generated as a jar file for the clients, more precisely the JSON response body
under the mappings
folder. There the java.util.Date
objects are serialized as timestamps, which is not consistent with the format used by the server (controllers), which is the iso_8601_with_offset
format. From what I've seen, these are the responses that the client will get from the Wiremock
server and they do not match the actual responses received by a client on the real server.
Can you show the contract, the generated test and the WireMock mapping?
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Here is the contract file:
name: search actors using criteria
request:
method: GET
url: /secure/v1.0/actors
queryParameters:
uuId: nsupuser
response:
status: 200
body:
- id: 1
uuId: nsupuser
lastReactivationDate: 2022-01-07T10:34:11.813+00:00
recUserId: hodor
recDate: 2022-01-07T10:34:11.815+00:00
modUserId: hodor
modDate: 2022-03-10T13:45:44.097+00:00
headers:
Content-Type: application/json
matchers:
body:
- path: $.[0].lastReactivationDate
type: by_regex
predefined: iso_8601_with_offset
- path: $.[0].recDate
type: by_regex
predefined: iso_8601_with_offset
- path: $.[0].modDate
type: by_regex
predefined: iso_8601_with_offset
here is the generated producer test:
import identity.domain.rest.server.IdentityRestBaseContractTestClass;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import io.restassured.module.mockmvc.specification.MockMvcRequestSpecification;
import io.restassured.response.ResponseOptions;
import static org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions.assertThat;
import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.*;
import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;
import static io.restassured.module.mockmvc.RestAssuredMockMvc.*;
@SuppressWarnings("rawtypes")
public class ActorsTest extends IdentityRestBaseContractTestClass {
@Test
public void validate_search_actors_using_criteria() throws Exception {
// given:
MockMvcRequestSpecification request = given();
// when:
ResponseOptions response = given().spec(request)
.queryParam("uuId","nsupuser")
.get("/secure/v1.0/actors");
// then:
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.header("Content-Type")).isEqualTo("application/json");
// and:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).array().contains("['id']").isEqualTo(1);
assertThatJson(parsedJson).array().contains("['uuId']").isEqualTo("nsupuser");
assertThatJson(parsedJson).array().contains("['recUserId']").isEqualTo("hodor");
assertThatJson(parsedJson).array().contains("['modUserId']").isEqualTo("hodor");
// and:
assertThat(parsedJson.read("$.[0].lastReactivationDate", String.class)).matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\.\\d+)?(Z|[+-][01]\\d:[0-5]\\d)");
assertThat(parsedJson.read("$.[0].recDate", String.class)).matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\.\\d+)?(Z|[+-][01]\\d:[0-5]\\d)");
assertThat(parsedJson.read("$.[0].modDate", String.class)).matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\.\\d+)?(Z|[+-][01]\\d:[0-5]\\d)");
}
}
and the generated json stub:
{
"id" : "114d2908-ecd5-4d51-af4c-3e4ffb360fd8",
"request" : {
"urlPath" : "/secure/v1.0/actors",
"method" : "GET",
"queryParameters" : {
"uuId" : {
"equalTo" : "nsupuser"
}
}
},
"response" : {
"status" : 200,
"body" : "[{\"id\":1,\"uuId\":\"nsupuser\",\"lastReactivationDate\":1641551651813,\"recUserId\":\"hodor\",\"recDate\":1641551651815,\"modUserId\":\"hodor\",\"modDate\":1646919944097}]",
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template", "spring-cloud-contract" ]
},
"uuid" : "114d2908-ecd5-4d51-af4c-3e4ffb360fd8"
}
is anybody taking a look at this? it's almost two months since the last update.
I didn't have time but if you're willing to help PRs are more than welcome!
Is this still a problem? Can we ask for a project that replicates this issue?
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
I'm facing an issue like this for an upgrade feature and I'm able to fix this by spying jackson bean like this :
@SpyBean
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
@BeforeEach
void setup() {
RestAssuredMockMvc.standaloneSetup(MockMvcBuilders.webAppContextSetup(applicationContext));
}
Hello,
I'm using
Spring Boot 2.6.3
andSpring Cloud Contract 3.1.0
andJackson 2.11.3
when writing contract ttests. This issue might be possibly related to the Maven plugin.I am having troubles when dealing with
java.util.Date
objects when writing contract tests using your wonderful library.First of all, I noticed that the default documented setup with
RestAssuredWebTestClient.standaloneSetup(controller)
does not use theJackson Object Mapper
of the application context. I was unpleasantly surprised to find out that the real application was generatingjava.util.Date
objects using theISO 8601 offset
format (2022-03-17T10:34:11.815+00:00
) but the application (context) used by the tests was generating thedate as timestamp
format (1641551651813
). I would say that here, when dealing with dates, there is a big possibility of not being aligned with what the real application would produce. I did not test the behaviour with the newJava 8
date time classes.Please note that the real application has no additional
Jackson
orJSON
configuration forSpring Boot
.I was able to overcome the issue by using something along the lines of manually injecting an
ObjectMapper
, creating anHTTP message converter
and setting it on an instance ofMockMvc
. Maybe the documentation should stress more that theMockMvc
configuration does not necessarily match the real one or give more details about how to configure it.In this way I was able to assert in a contract file that the date format matches a predefined format
iso_8601_with_offset
using dynamic body matchers in ayml
file.But then, when running the tests on the client consumer side, I noticed that the
JSON
which the client sees has the dates still in thetimestamp
format. I checked the generated stubs and their mappings and, indeed, the dates are not using theiso_8601_with_offset
format. I don't understand why and I could not find where the problem comes from.Once again, I would like to point out that there is no special
JSON
Spring Boot
configuration in the application, just the default one, as far as I'm aware.Any ideas why and how to get the dates in the same format, in the contract tests on the producer and the generated stubs used by the consumer?
Many thanks, Virgiliu