If you have been reading Martin Fowler’s canonical article on the test pyramid, you know that there is a mystical layer that hides between those braod unit tests (the base of the pyramid) and the integration tests layer (near the top). This layer is called: component tests. This article is about the following : What are component tests? Why should you care, and how to implement them properly?
What are component tests and why should you care?
Basically component tests are the the part that theoretically should allow you to isolate a specific “component” of the system and test it individually. For instance – if you have been using a remote billing service and you want to check the part of your code that works against it as easily and quickly as possible you’ll create a billing service mock. Note, that we are not talking here about unit tests that should cover you individual functions, nor do we talk about running the whole app against all external services as we do in integration testing. We isolate one external system or more (DB,queue, remote API, redis cache and etc) and test how your code works against it as quickly and as easily as possible.
So how is this different from integration tests?
We can test each component individually
We can do it locally without having to spin the whole app with real connectivity to the outside world. So for instance, instead of using a real DB – we will use an in-memory local DB that supports your flavor of SQL. Instead of connecting to a remote Redis server we will launch a local one, instead of connecting to an actual “real” micro-service we will connect to a mock micro-service that implements the same interface and etc. *This* will give us the ability to detect bugs early, by running more tests in less time.
If you don’t interact that much with external components and/or have a full blown “demo” environment on your laptop then maybe creating such a component tests framework won’t be worth your time. Otherwise – the effort (at least from my experience) is well worthwhile.
How to create a proper component test framework?
I’ll give here some general and language neutral guidelines and I’ll dive into some specific examples for Java developers for what is needed to create this kind of framework:
- Identify the main components (pun intended) your code works with. Examples of such components can be:
- DBs (SQL and NoSQL)
- External systems (REST API of different varieties)
- Caching mechanisms (memcached, redis)
- and etc
- Create a mock entity for each
- To create component tests for RESTful APIs you need to make sure that you implement the same interface as the classes you mock and that you keep the responses format the same (except for the data of course). Keep in mind that you should also clone the input validation and other server logic from the “real” service as you will want to mock. You want to make sure that when your real services throws an error so does your mock.
- Part of your test orchestration should contain “pre-seeding” of your mocks. For instance, creating the schema and initial data for the DB (can be done using migrations) and setting the return values of the different API services.
- In addition, it will be useful to be able to decide on the fly which of the components will be run as a mock and when to call the “real” component. In Spring Boot for instance this can be accomplished with Spring Profiles.
Actual mocking tools for Java developers
- SQL DB: H2
- MongoDB: Local Mongo Server
- Redis: Local Redis Server
- Webserver (to mock REST requests)
- Migration mechanism for seeing SQL DB: liquibase
- Migration mechanism for seeding MongoDB: mongobee
Thanks all for now folks.