Search code examples
jodatimespring-cloud-contract

Spring Cloud Contract DSL verify date format


How can I verify the date format in a contract? I ran into an issue a while ago where my service inherited an object mapper that changed the format of the dates my service returns from milliseconds to timestamps. I'm trying to write a contract that would catch the date format change. Here's what I put in my contract:

response {
    status 200
    body(
            time: 1505276760077L
    )
}

Here's what I'm playing with in my object mapper:

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JodaModule());

    /*
    uncommenting this cause DateTime format to change from 
    milliseconds to timestamp
    i.e., 1505276760077 changes to 2017-09-13T04:26:00.077Z
    Either way, the test passes
     */
    // objectMapper.configure(SerializationFeature
               .WRITE_DATES_AS_TIMESTAMPS, false);

    return objectMapper;
}

The test passes regardless of the format the date is in. Is there some way to make the test fail when the format changes?

I have a sample project here if that helps: https://github.com/rtteal/consumer-driven-contacts-demo

Update:

I tried updating my contract to use a regex, but that still doesn't cause my test to fail when changing the object mapper.

response {
    status 200
    body(
            time: $(regex('[0-9]{13}'))
    )
}

This is the relevant part of the generated test:

assertThatJson(parsedJson).field("['time']").matches("[0-9]{13}");

The test seems to be ignoring the object mapper config. Do I need to do something to make it pick up the object mapper when the test is run?


Solution

  • You can use a regex for dates (http://cloud.spring.io/spring-cloud-static/Dalston.SR3/#_regular_expressions). Then a valid date will get generated for you. You could also set the low value of the priority field (that means a higher priority). If you need to create a separate contract for an invalid date, what you can do is create such a pair for date that will match nonBlank() value. Set a higher value of the priority field (that means a lower priority). That way you'll have 2 contracts for the same URL that verify 2 behaviors. 1) Valid date, 2) invalid date

    UPDATE:

    You are using MockMvc with a standalone setup. That means that it ignores any context configuration that you have. If you want the bean that you have created to be taken into account, here (https://github.com/rtteal/consumer-driven-contacts-demo/blob/master/src/test/java/com/example/DemoBase.java#L17), use the webAppContextSetup method. Check this page - https://piotrminkowski.wordpress.com/2017/04/26/testing-java-microservices/ for an example.