0% found this document useful (0 votes)
2 views18 pages

Microservices Patterns - Testing Microservices VII

The document discusses integration testing for microservices using a publish/subscribe model, emphasizing the need for services to agree on message channels and domain event structures. It outlines the testing approach for both provider and consumer sides, detailing how to verify that events are published and consumed correctly. The document also includes examples of consumer-driven contract tests for the Order Service and Order History Service, ensuring that both sides adhere to the defined contracts.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views18 pages

Microservices Patterns - Testing Microservices VII

The document discusses integration testing for microservices using a publish/subscribe model, emphasizing the need for services to agree on message channels and domain event structures. It outlines the testing approach for both provider and consumer sides, detailing how to verify that events are published and consumed correctly. The document also includes examples of consumer-driven contract tests for the Order Service and Order History Service, ensuring that both sides adhere to the defined contracts.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Microservices Patterns

Testing Microservices VII

Integration Testing Publish/Subscribe-Style


Interactions
Integration testing publish/subscribe-style interactions

● Services often publish domain events that are consumed by one or more other
services.
● Integration testing must verify that the publisher and its consumers agree on the
message channel and the structure of the domain events.
● Order Service, for example, publishes Order* events whenever it creates or updates an
Order aggregate.
● OrderHistory Service is one of the consumers of those events. We must, therefore,
write tests that verify that these services can interact.
Integration testing publish/subscribe-style interactions

● The following figure shows the approach to integration testing publish/subscribe


interactions.

● It’s quite similar to the approach used for testing REST interactions.

● As before, the interactions are defined by a set of contracts.

● What’s different is that each contract specifies a domain event.


Integration testing publish/subscribe-style interactions
Integration testing publish/subscribe-style interactions

● Each consumer-side test publishes the event specified by the contract and verifies
that OrderHistoryEventHandlers invokes its mocked dependencies correctly.

● Each consumer-side test publishes the event specified by the contract and verifies
that OrderHistoryEventHandlers invokes its mocked dependencies correctly.
Integration testing publish/subscribe-style interactions

● On the provider side, Spring Cloud Contract code-generates test classes that extend
MessagingBase, which is a hand-written abstract superclass.
● Each test method invokes a hook method defined by MessagingBase, which is
expected to trigger the publication of an event by the service.
● In this example, each hook method invokes OrderDomainEventPublisher, which is
responsible for publishing Order aggregate events.
● The test method then verifies that OrderDomainEventPublisher published the expected
event.
The Contract For Publishing An Ordercreated Event

[Link] {
label 'orderCreatedEvent'
input {
triggeredBy ('orderCreated()')
}
outputMessage {
sentTo('[Link]')
body('''{"orderDetails":{"lineItems":[{"quantity":5,"menuItemId":"1",
"name":"Chicken Vindaloo","price":"12.34","total":"61.70"}],
"orderTotal":"61.70","restaurantId":1,
"consumerId":1511300065921},"orderState":"APPROVAL_PENDING"}''')
headers {
header('event-aggregate-type',
'[Link]')
header('event-aggregate-id', '1')
}
}}
The Contract For Publishing An OrderCreated Event

The contract also has two other important elements:

● Label—is used by a consumer test to trigger publication of the event by Spring Contact

● TriggeredBy—the name of the superclass method invoked by the generated test


method to trigger the publishing of the event
Consumer-Driven Contract Tests For Order Service

● The provider-side test for Order Service is another consumer-driven contract


integration test.

● It verifies that OrderDomainEventPublisher, which is responsible for publishing Order


aggregate domain events, publishes events that match its clients’ expectations.

● The following listing shows MessagingBase, which is the base class for the test
classes code-generated by Spring Cloud Contract.

● It’s responsible for configuring the OrderDomainEventPublisher class to use


in-memory messaging stubs.

● It also defines the methods, such as orderCreated(), which are invoked by the
generated tests to trigger the publishing of the event.
Consumer-Driven Contract Tests For Order Service

@RunWith([Link])
@SpringBootTest(classes = [Link],
webEnvironment = [Link])
@AutoConfigureMessageVerifier
public abstract class MessagingBase {
@Configuration
@EnableAutoConfiguration
@Import({[Link],
[Link],
[Link]})
public static class TestConfiguration {
@Bean
public OrderDomainEventPublisher
OrderDomainEventPublisher(DomainEventPublisher eventPublisher) {
return new OrderDomainEventPublisher(eventPublisher);
}
}
Consumer-Driven Contract Tests For Order Service

@Autowired
private OrderDomainEventPublisher OrderDomainEventPublisher;
protected void orderCreated() {
[Link](CHICKEN_VINDALOO_ORDER,
singletonList(new OrderCreatedEvent(CHICKEN_VINDALOO_ORDER_DETAILS)));
}
}
Consumer-Driven Contract Tests For Order Service

● This test class configures OrderDomainEventPublisher with in-memory messaging


stubs.

● orderCreated() is invoked by the test method generated from the contract shown
earlier. It invokes OrderDomainEventPublisher to publish an OrderCreated event.

● The test method attempts to receive this event and then verifies that it matches the
event specified in the contract. Let’s now look at the corresponding consumer-side
tests.
Consumer-Side Contract Test For The Order History
Service

● Order History Service consumes events published by Order Service. the adapter class
that handles these events is the OrderHistoryEventHandlers class.
● Its event handlers invoke OrderHistoryDao to update the CQRS view.
● The following listing shows the consumer-side integration test. It creates an
OrderHistoryEventHandlers injected with a mock OrderHistoryDao.
● Each test method first invokes Spring Cloud to publish the event defined in the
contract and then verifies that OrderHistoryEventHandlers invokes OrderHistoryDao
correctly.
The consumer-side integration test for the
OrderHistoryEventHandlers class

@RunWith([Link])
@SpringBootTest(classes= [Link],
webEnvironment= [Link])
@AutoConfigureStubRunner(ids =
{"[Link]:ftgo-order-service-contracts"}, workOffline = false)
@DirtiesContext
public class OrderHistoryEventHandlersTest {
@Configuration
@EnableAutoConfiguration
@Import({OrderHistoryServiceMessagingConfiguration .class,
TramCommandProducerConfiguration .class,
TramInMemoryConfiguration .class,
EventuateContractVerifierConfiguration .class})
public static class TestConfiguration {
The consumer-side integration test for the
OrderHistoryEventHandlers class

@Bean
public OrderHistoryDao orderHistoryDao() {
return mock([Link]);
}}

@Test
public void shouldHandleOrderCreatedEvent() throws ... {
stubFinder. trigger("orderCreatedEvent");
eventually (() -> {
verify(orderHistoryDao)
.addOrder(any([Link]), any([Link]));
});
}
}
The consumer-side integration test

● The shouldHandleOrderCreatedEvent() test method tells Spring Cloud Contract to


publish the OrderCreated event.

● It then verifies that OrderHistoryEventHandlers invoked [Link]().

● Testing both the domain event’s publisher and consumer using the same contracts
ensures that they agree on the API.
The Next Post

Integration contract tests for


asynchronous request/response
interactions

You might also like