Hi Johan,
I like you proposed solution and it is quite similar to ours.
What we do is quite the same: We add an interface to define an upcasting process for a single (JSON-serialization of an) event (qualified name), a single source revision, and a single target revision. Implementations of those interface are wired to build the whole EventUpcasterChain, meaning that the Upcaster internals like the "IntermediateRepresentations" are not visible in our interface. Testing can be done as follows:
- We unit test the implementation of our interface by adding (copying) the source revision of the target event as a new private class to test file. Then we serialize the copied event, run the implementation of our interface, and deserialize to the new target revision, again.
- We try to unit test the overall Upcaster that gathers all the above mentioned interface implementations. But this is not easiliy possible as the methods are protected. After changing it to public (which seems wrong) we were able to unit test with mocked IntermediateRepresentations. This is not ideal, but at least it works. The main idea is that we do only want to test the overriden methods of the Upcaster interface but not the internals of Axon.
What we also lack (or at least hoped to find) was a solution to test the Upcaster easily, e.g. using a fixture in an aggregate test. It would be nice to be able to inject an event to the Datastore at the beginning of a test run with a given (custom) qualified class name, revision, and a custom payload. The main problem is that there can always only be a single class with the given qualified name and thus only changing the revision (which is what we expect to be sufficient for upcasting) does not work for tests. I know that a workaround like adding the revision to the event class name solves this issue but this is not the way I would like to see Axon working. (Then the revisions are more or less useless.) It would be really great to make Upcaster testing easier and hopefully, such a feature will be added in the future.
Best regards,
Markus