Mocking Providers and HTTP Responses

This article is about how I mocked a service that used HTTP calls to get data to and from a server, then used environment variables to toggle whether the real or fake service is used. Here, the mock service returns data from a local file in the body of an HTTP response within an Observable.
Here’s an example of a service to be mocked:
As a fresh-faced intern, being tasked with this was a little daunting, but I had been in computer science long enough to know that Google is your best friend. During my search, there were a few different tools consistently floating around in the results, but these required some editing of the components, and didn’t allow for the isolated solution I was looking for. I just needed something to produce HTTP responses within a service!
After sifting through lots of articles about unit testing and other things I didn’t know about, I found my solution on this blog. Here’s the part that was actually helpful to me:
Wow, exactly what I needed! It returns an Observable of type Response, just like the original service, and the contents of the Response can be configured, so that functions dependent on this response can still… function.
One thing that this snippet of code brings up though, is that you need some mock data to put into the body. In a separate file, I assigned the mock data to variables that I then imported into the mock service file. Here’s how my files ended up looking:
Mock Data:
Mock Service:
postSkills() looks a little freaky, but there’s only two extra things. getSkills() is almost copy-pasted from that blog post, except that I replaced mockUsers with mockSkills.
In postSkills(), the response body is now an object with data from the argument. This was necessary for some of the functions because throughout the app I was working on, functions of other components relied on information in the response body returned by the post methods of the original service.
The second new thing in postSkills() is that it pushes an object onto the mockSkills list using properties of the object passed in for the data parameter. The shape of the pushed object is just determined by the shape of the objects in the mockSkills list already.
Now that the mock service is complete, we can get data from a local file and post to variables from that file. However, this mock service’s posting doesn’t actually alter anything in the file, so anything POSTed during manual testing of your app won’t persist between runs.
The last part of this task was to switch between my mock service and the real service based on environment variables, namely environment.production, which tells whether it’s in production mode or development mode.
This takes place in the providers property of ngModule’s configuration object and makes use of the provider object literal. It ends up looking like this inside the app module:
provide is the name that the service can be accessed with (the token), and useClass is what actually gets provided. This is why the real service and mock service should have the same exact function names. In useClass we use a ternary operator to provide SkillsService if enrivonment.production is true, and MockService if it’s false.





