Consider an Integration project in which the timelines of the different layers make it hard to synchronise the development and test phases across different systems. Or an application integrating with an external system that charges for every call made. Wouldn't it be desirable to limit the paid invocations to such systems during the development phase? How about a multi-environment application which only has one downstream environment available to interact with? These and many such scenarios make it necessary for a reusable, lightweight and intuitive application which can, in essence, be used as a replacement for one or more of the interfacing systems, applications or layers.
Stubs are well-known in the Test-Driven Development world. Essentially, a stub is an implementation which the System Under Test or SUT can call to get predetermined responses/errors. They serve as an alternative to the intended endpoint and can be used for testing the implementation of the SUT. Stubs are different from Mocks in that a mock implements the same interface as the SUT object. There are other entities such as Spies and Dummies used for similar and different purposes. In the context of large-scale integration projects (AKA Digital Transformation), the application of TDD takes a new, multipurpose and multifaceted form. The SUT becomes a whole application or even a complete layer of the Integration Architecture. The stubs have to play the roles of all the other characters from the TDD stable. In this blog, we will visit one of the more intricate and versatile approaches to using a stub.
Christened by Ali Nikkhah, Principal at Deloitte Platform Engineering, the Smart Stubbing Framework was implemented at one of the recent major digital transformation initiatives delivered by Deloitte. The framework proved instrumental in the Integration Platform as a Service, or iPaaS layer. There were many purposes served by the framework over the course of the project:
In essence, the stubs are realised as a MuleSoft application. They would use the same contract as the system/layer being stubbed. They would implement all the flows in scope. Each of these flows would have choice routers serving different responses. The configurations are designed to be as close to the endpoints being stubbed. This would ensure that the switch from stubs to the real endpoints is as frictionless as possible.
The design phase of the stubs would involve two major steps:
Integration Interface & URI | Actual API | Request to Response Correlation Logic | Covered Test Cases |
Validate Email Addresses URI: /email/validation/v1 |
Validation → External (Experian) REST | Correlation of the incoming email address to specific statically created response payloads. |
|
Validate Phone Number URI: /phone/validation/v1 |
Validation → External (MSISDN) REST | Correlation of the incoming phone number to specific statically created response payloads. |
|
Implementation of the stubs would be similar to that of a Mule application with the key difference appearing at the business logic implementation stage. The project creation and packaging should follow best-practices. Depending on whether the application contract is a WSDL or a RAML, the flows can be generated. In Anypoint Studio (MuleSoft’s IDE), it is possible to generate the flows automatically. Alternatively, the entry point to the stub can be an HTTP listener which delegates the routing strategy to an APIKIT router (or an APIKIT for SOAP router).
A sample entry flow for the stubbing flow would look something like this:
Subsequently, the router would take the control into the respective flow wherein the conditional responses are returned. This is illustrated in the sample flow below:
The choice routers can be based on business logic which would drive the different response scenarios. The responses can be populated by using Parse Templates. Other alternatives are to use payload transformers in Dataweave, Groovy or Spring beans.
An example of Groovy Engine being used for payload creation:
The response should conform to the contract being used. The error responses and negative test scenario responses were aligned to the interface contracts of the integrated systems.
Implementing the same contracts also means that the same API Policies can be applied to the stubs as the intended system.
Over the course of the project, several occasions prompted a thorough analysis of the way we were using the stubs:
It was a learning experience to be a part of the iPaaS team which entailed having full ownership of the Smart Stubbing Framework. The first phase was implemented by Ali himself. Other notable contributors were Becky McCreath, Vittoria Capuano and a very enthusiastic vacationer cohort. I would like to thank the entire iPaaS development and testing team for contributing to the Smart Stubbing Framework in varying capacities.
The most powerful aspect of the framework is its simplicity. Keeping it aligned to the business requirements helps to ensure that they can be maintained and augmented as the requirements evolve. As the entire business logic is driven by conditional programming and pre-determined responses, once the framework is established, it is easy to enhance or modify. It can be adapted to practically any architecture and any technology stack for similar results. Should you wish to know more, we would be glad to share details about the journey. Please get in touch with any queries or comments about the framework.