Open dominikbrandon opened 1 year ago
Hi, thanks for feedback. This is something that's on my mind for years. All JsonUnit assertion methods are basically static or have a static entry-point. This does not play well with the dynamic nature of Spring. There are two out of this
I see, thanks for the response. What about kind of mixing those two? I mean some static function that would allow you to provide an ObjectMapper instance and then JsonUnit would internally store it in some static field. In my opinion, it would be quite easy to use - it would allow you to call this static function inside the setup method, which would be easy for both: creating and configuring your own instance manually, or using the one autowired by Spring. I believe some people would still prefer to not worry about ObjectMapper at all, so there could be a default one. What do you think about that? The difficulty here would be to provide backward compatibility for providing ObjectMapper using SPI, but I believe this will be possible to achieve in some way.
In case the description is unclear, I mean something like this (it's Groovy+Spock):
abstract class IntegrationSpec extends Specification {
@Autowired
ObjectMapper objectMapper
def setupSpec() {
JsonUnitNewConfigClass.injectObjectMapper(objectMapper)
}
}
Yes, that would be possible. I am reluctant to add this as it is quite brittle and I do not want to be solving issues of people using it incorrectly. You can do the same using Jackson2ObjectMapperProvider
Why do you consider this solution brittle? I feel like it's a clear and explicit way of providing ObjectMapper instance and I'm just curious what exactly makes you feel that it's the wrong approach.
And regarding the point that you can do the same using Jackson2ObjectMapperProvider
- yes, you're right. I've made it this way and it seems like it's working seamlessly. But doing so made me feel like I'm hacking it - I was particularly worried about a possible NullPointerException in the case of JsonUnit trying to use ObjectMapper before it's been autowired. Yes, it should have been because usually you first run the application which makes the whole Spring context start, then you execute some actions, and finally, you assert using JsonUnit. So assuming that ObjectMapper gets loaded from Jackson2ObjectMapperProvider only when one of the JsonUnit's methods gets called, this would, and does, work. But I didn't know when exactly JsonUnit does that - maybe it's at the start of the execution, or right after that.
Anyway, maybe a cheap and good enough solution would be to put a hint in the docs on how the ObjectMapper may be provided when using Spring, what are your thoughts about that? Maybe this will be helpful for future users of the library.
Just a note for my future self. I tried to implement it and the trouble is that AssertJ style tests are currently parsing the value before any configuration can happen -assertThat(json)
is parsing the value before any other method can be called.
Workaround - instead of string, you can provide Jackson JsonNode. Instead of assertThat(jsonString).isEqualTo(jsonString2)
you can do assertThat(m.readTree(jsonString)).isEqualTo(m.readTree(jsonString2))
Summary I've got a case where I need to customize the ObjectMapper instance used by JsonUnit, moreover, I don't want to create a new instance of it, but rather use the one provided by Spring context instead.
Solution I'd like A way to set up JsonUnit's ObjectMapper programmatically instead of via SPI, e.g.
Do you think something similar would be possible to implement?
Alternative solution I've come up with a workaround for that, but it's not too good, as there might appear an NPE when JsonUnit tries to access ObjectMapper before Spring autowires it.