0

I really like the concept of using failed tests to ensure the documentation is up to date. But I don't know how to make it work for nested json. The way Spring REST Docs handles hierarchical payload seems to defeat the purpose:

When documenting fields, the test will fail if an undocumented field is found in the payload. Similarly, the test will also fail if a documented field is not found in the payload and the field has not been marked as optional. For payloads with a hierarchical structure, documenting a field is sufficient for all of its descendants to also be treated as having been documented.

How would you write your tests for nested json so changes to the payload result in a failed test?

Example:

{
car: {
    motor : {
        brand: "Porsche",
        power: "165 kW"
    },

    suspension: {
        type: "automatic"
    }
}

Test:

.andDo(document("mytest", responseFields(
                    fieldWithPath("car").description("the car").type(JsonFieldType.OBJECT),
                    fieldWithPath("car.motor").description("the motor").type(JsonFieldType.OBJECT),
                    fieldWithPath("car.motor.brand").description("the motor brand").type(JsonFieldType.STRING),
                    fieldWithPath("car.suspension").description("the suspension"))))

A test with these response field definitions would pass even though car.motor.power and suspension.type are not defined. Is there a way to make it work? Multiple tests?

1 Answers1

0

The intent was to allow people to document all of the fields if they wanted, without forcing them to do so. However, as you have observed, it can lead to a new field in the API being missed. With hindsight, this was probably a mistake.

One way to avoid missing a new field is to only document "leaf" fields. In your example that would be:

  • car.motor.brand
  • car.motor.power
  • suspension.type

You could do this in a separate test if you also wanted to keep the more detailed documentation. Another alternative would be to use something like JsonPath to assert the structure of the payload.

I realise that none of these is ideal so I've opened https://github.com/spring-projects/spring-restdocs/issues/274.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • Thanks a lot for your quick reply and action. It would be really great if you could resolve the issue. Maybe a solution would be to add a property to the FieldDescriptor so you you can en/disable strict checking per field? For now I will probably try to solve it by using separate tests. – timbamania Jul 07 '16 at 09:52
  • Wouldn't the test fail if brand is documented but power isn't? – Andreas Evers Jul 07 '16 at 11:25
  • No, I don't think so. If you've documented `car` or `car.motor` then everything beneath `car` or `car.motor` is considered as having been documented. – Andy Wilkinson Jul 07 '16 at 11:43
  • Perhaps the best solution here would be that all siblings of a documented field should be documented? So in that case if you document `car.motor`, `car.suspension` should be documented as well - but not any subfield of these two. If you document `car.motor.brand`, then you have to document `car.motor.power` as well. Consequently, if a new field is added in the payload, it will always be breaking your test unless you never documented a single field on the level it is added to. – Andreas Evers Jul 07 '16 at 13:13
  • @AndreasEvers Interesting idea, but I think this is not the solution. Imagine I change car.motor.power like this: `{ car: { motor : { brand: "Porsche", power: { unit: "kW", amount: "165" }, }, suspension: { type: "automatic" } }` This will pass the test. – timbamania Jul 07 '16 at 15:28