spring-cloud-contract
spring-cloud-contract copied to clipboard
Cannot test Spring Cloud Stream Batch Mode using the test binder and Spring Cloud Contract
Hi,
In Summary Spring Cloud Contract and spring cloud stream test binder in batch mode are not working quite right. I have a boot 2.6.8 Cloud 2021.0.3 project https://github.com/davidmelia/spring-boot-webflux-avro-sink-only-batch which shows this issue in isolation:
I have two consumers:
- StaticInstrumentEventBatchConsumer - consumes batch events
- StaticInstrumentEventConsumer - consumes a single event
and two corresponding spring cloud stub runner integration tests:
- FxRateBatchIntegrationFailingTest - fails because the payload is a Message<byte[]> instead of a Message<List<AvroFxRateEvent>>
- FxRateNoneBatchIntegrationTest - works fine
FxRateBatchIntegrationFailingTest shows the problem. When running in batch mode the event is a Message<byte[]> instead of a Message<List<AvroFxRateEvent>>. In the logs you see
Processing Batch: GenericMessage [payload=byte[39], headers={
where the payload is a byte array which is incorrect
To prove this is only a test problem you can create a kafka 'test' topic and use the KafkaTopicPopulator to populate, start the app and you will see batch messages consumed with the correct payload in the log:
Processing Batch: GenericMessage [payload=[{"from": "GBP", "to": "USD", "rate": 0.109631}, {"from": "GBP", "to": "USD", "rate": 0.109631} ...
where the payload is correctly an array of AvroFxRateEvent objects.
Thanks
N.B this is actually the same issue https://github.com/spring-cloud/spring-cloud-stream/issues/1925 which didn't progress although no reason was given.
I will transfer i to spring-cloud-contract, as it appears fro your description that contract may have some wrong assumptions about what the payload type must be. The byte[]
is what is expected by the s-c-stream
I would suggest not to use the test binder but go with testcontainers and an actual binder like we do it e.g. here https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/3.1.x/producer_kafka_middleware
@marcingrzejszczak obviously this is your call but my take is: spring cloud contract has first class support for testing messaging communication and supporting batch seems to be a short hop from the current support. I suppose this issue may be a feature request rather than a bug.
I could test via test containers however the beauty of spring cloud contract + spring cloud stream integration is the simplicity and speed.
Would this be something you would consider supporting?
I'm running into the same issue. is there a way batch mode can be supported in test binders?
The short answer is no and we have no plans to do so. Here is why. . . Batching often supplemented by the underlying functionality of the messaging system. For example, RabbitMQ prefetch. Similar things exist for Kafka etc. . . And in fact if you look at extended binding properties just between Kafka and Rabbit you'll see quite a few differences which are all based on supported functionality. So, basically there is no generic case that could be reliably implemented to emulate this or that system.
Further more, the TestBinder was initially created for internal use to primarily support internal testing of the core binder API and to replace the old MessageCollector that did not do that. We quickly realised that it could be used for majority of the unit testing based on core functionality, so users can benefit from it as well. However TestBinder was never meant to replace or replicate a real binder tied to a particular messaging system. So this is where integration testing should really be done and between Docker images and embedded messaging systems (i.e., Kafka) I don't see a reason fort test binder to attempt to reproduce (re-implement) some of the functionality specific to a particular messaging system. Also how would we manage the subtle differences in such functionality between let's say Kafka and Rabbit? And what about binders we don't know about?