Component Testing for Event-Driven Microservice
We will see what to have in component tests for an event-driven microservice and understand what component testing is and how it's different from unit testing.
Join the DZone community and get the full member experience.
Join For FreeIn an event-driven architecture, the microservices are often integrated using the pubsub (publisher-subscriber) model and connected to each other by messaging platforms such as Kafka, RabbitMQ, etc. Typically a microservice in event-driven architecture acts either as producer/consumer or both.
In this post, we will see what to have in component tests for an event-driven microservice. But before that, we will understand what component testing is and how it's different from unit testing.
What Do I Mean by Component?
Anything! A group of multiple units working together to accomplish a sub-journey of a longer user journey of the microservices lifecycle. Example:
A longer end-to-end journey:
Login > Compose a mail > Send it > Check the status in sent mail > Logout.
Different components of the longer journey:
Login > Compose a mail > Send a mail > Check the status in sent mail > Login > Logout > etc.
In a microservices architecture, a service itself can be considered as a component.
How Different It Is From Unit Testing?
Unit tests are intended to ensure that a method/class works as expected. On the other hand, component tests are primarily focused on a smaller user journey (in the case of event-driven architecture domain events). Component tests fill the gap between a unit test and an E2E test as the unit test is too small to give you the feedback of a domain event and E2E is too costly to test the unhappy scenarios of a component. Component tests are like end-to-end tests within the boundary of service.
Few points to take care of while adding component tests:
- Component tests should be running with Unit Test Suite.
- Should be compiled along with the service itself.
- Should not depend on external components (or peer systems). The external components should be replaced by TestDoubles.
- Preferably using in-memory services.
- Should be able to give you feedback for unhappy responses from external systems.
- TestContainers could be a good choice to run the throwaway instances of services like Kafka, CouchBase, etc.
- Should be slower than unit tests but faster than the E2E test.
- One should be able to run component tests without any prerequisites or configuration changes.
Component Tests for Event-Driven Microservices
A typical microservice in event-driven architecture may act as below:
Producer Microservice
When a trigger is hit, microservice produces events for other microservices to consume.
What to Test at Component Level:
We will follow the Arrange-Act-Assert pattern to write our tests.
Arrange — Setup prerequisites for the test.
Act — Hit the trigger point to produce the event by microservice.
Assert — Assert the event produced by microservice against the contract of its consumer.
Consumer Microservice
Consumer microservice is always listening on a topic and when an event is produced on it, the consumer microservice acts immediately. It may perform a CRUD operation in a database.
What to Test at Component Level:
Arrange — Setup prerequisites.
Act — Produce an event on the topic where our microservice is listening.
Assert — Assert the intended action of microservice. If it updates any entity in the database, having assertions for the database entity would be a good check.
Consumer and Publisher Microservice
In some cases, a microservice would be given a responsibility to consume events on a certain topic which works as a trigger point for the producer side of the service.
What to Test at Component Level:
Arrange — Setup prerequisites.
Act — Produce an event on the topic where our microservice is listening. This will trigger the producer side of the microservice.
Assert — Assert the event produced by microservice against the contract of its consumer.
Challenges of Component Testing in Event-Driven Architecture
- Setting up prerequisites. If in scope microservice has dependencies on multiple other services then one can face difficulties in setting up testdoubles.
- Kafka consumers in Test, if you are testing the producer side of microservice and want to verify events produced by it. It needs a consumer running in the test which may make the test susceptible to intermittent failures.
A trade-off between test maintenance and achieving the intent of the test.
Summary
In a sense, component and unit tests share some similar characteristics. Both of them are added in the same codebase, run together to accomplish different goals. Component test reduces the burden from the end-to-end test as smaller user journeys with happy/unhappy paths are already covered at the service level. So next time you are about to write an end-to-end test, a thought can be given to have tests at component level instead.
Opinions expressed by DZone contributors are their own.
Comments