Mocking with Angular: More than just unit testing
When one speaks of mocking in the programming circles, we often think of mocking objects for unit testing. While this is a very valuable practice, there are intrinsic benefits we often overlook that we can do with mocking. I’m going to show you how to increase your development speed and improve quality (outside of unit tests) with mocking. Have I got your attention?
How do you increase development speed with mocking?
In many organizations, the responsibilities of front-end and back-end are split between teams. A new project kicks off and we as front-end developers typically lag behind the back-end team hooking up services once they become available. But what if both teams could work in parallel? What do we need to achieve this?
API specifications describe the models and the endpoints of the service contract. They serve as a single source of truth for the contract between the client and the backend. There are numerous tools out there to help achieve this in a standardize format like like OpenAPI (f.k.a. Swagger) or RAML.
Everyone should be involved in this process of flushing out this spec. It should be no different than going over business requirements. Once both teams have a agreement, the respective teams can go off and start their work.
In order for the UI to start progression while the backend is still in works, you need some way to mock the response from the data. Typically I see this done in 2 different ways:
- Backend developers create the stubs and just return hardcoded data. This requires the front-end users to run the backend while its very unstable, lead time for the back-end developers to build this out and they maintain it making it difficult to get different data for your testing
- Frontend API functions don’t actually call any backend but just hardcode the data in. This gets really messy fast.
Luckily for you, Angular has your back covered! There is a little known tool in the Angular repo called In Memory Web API. Once installed this library will intercept all your HTTP calls and return mock data for you. You don’t have to hardcode anything or rely on your backend team anymore. The tool makes everything seamless even mimicking delayed responses if you want it too. You can set headers, response types, basically everything you might do with a server.
Its really easy to hook up, lets install it as a dev dependency since we probably only want this for our development environment:
npm i angular-in-memory-web-api -D
Next, we need to include it in our module. Typically I conditionally include it using an environment flag like this:
Now when I run my app in production mode, it will get real data. Lets write a quick service that will return a list of heros.
And then create a
InMemoryDbService that creates a ‘db’ with an array of heros.
And thats it! When you run your application in dev mode, instead of calling out the the API endpoint, the In Memory DB will intercept it instead and return this data for us.
You can see a end-to-end demo of this here: https://stackblitz.com/edit/angular-feature-modules-example?embed=1&file=app%2Fapp.module.ts&view=editor
How do we improve quality with mocking?
If we look at the in memory db implementation I posted above, its pretty simple looking but lets face it real world data doesn’t have 2 properties and they are much more complex. We could spend hours trying to make methods that generate random data based on timestamps or copy and paste HUGE blocks of JSON into our app.
We as developers are pretty optimistic; meaning if we paste 100 objects in a JSON file and just return that we will code for that scenario. What if there is no response from the server? What if there is a million? How do we code for these dynamic situations without re-implementing a backend on our frontend?
Meet Faker.js. Faker is a tool that can generate TONS of different data attributes for you. For instance, it can generate random names, future/past dates, credit card numbers and the list goes on. We can leverage this tool to do all our fake data generation in our services for us. Because this data is completely random, we see scenarios that wouldn’t typically take place with hardcoded data. Its super easy to plug this into our in memory db we just learned how to use too! Take a look at this example I built recently.
This makes a random number of hosts with random attributes within them. This is a essential tool in any programmers toolbar.
Putting it all together
Having the ability to quickly make fake services returning random data gives us maximum efficiency to develop quality code quickly. We no longer have to lag behind backend teams, wait for fake endpoints or hardcode data in our services with tools and methods like these. We can build in parallel to our team and flip a switch at the end.