Artful DI in Angular – Part 2: How to create a mock HTTP service

When developing an application in Angular, you often need to mock up an HTTP service to mimic communication with the server. Maybe you want a mock to inject into your unit tests, or maybe the server-side developer just can’t keep up with you and doesn’t have their API ready yet. In this post, we’ll see how to create a service method that works just like an HTTP call in Angular, but without the HTTP part!

The idiomatic way to program HTTP services in Angular is with the RxJS Observables that come bundled with Angular. You can read all about it in Angular’s introduction to their HttpClient. Yes, you can still use good old Promises or even XMLHttpRequest calls but you’ll miss out on the power of RxJS.

That power will be demonstrated in the sample service of this post. You’ll see that it’s easy to compose RxJS’s Observables to imitate both success and failure conditions. When the time comes to make real HTTP calls, you can swap in Angular’s HttpClient and it should work just the same.

Recall from Part 1 of this series that our scenario was looking up produce in a grocery-store application based on Produce Lookup (PLU) codes. We represent this with the very simple ProduceRecord class. Our mock produce-lookup.service.ts has an array of those records and and it does lookups in the lookup method.

Here are some things to notice about the lookup method.

  • It returns an Observable<ProduceRecord>. This allows its callers to wait on the results in a way that is similar to (but not quite the same as) Promises. I’ll show that code in a moment.
  • If there is an immediate problem (PLU not 4 or 5 digits), the method calls throwError. This is from RxJS and will cause the waiting code to go into its error branch. It is not the same as a JavaScript throw.
  • If a matching record is found:
    • The method first makes an Observable out of it with RxJS’s of function. This function is able to make an Observable out of just about anything. That’s the power of RxJS at work!
    • Next it pipes that Observable into another method, delay, which mimics the delay we might get with a real server call. In the finished application, we will apply a CSS class to the PLU Code field while the lookup is pending, and another class when the lookup succeeds. The delay will let us see the effect. RxJS’s pipe function is the preferred way to compose functions that act on Observables and produce other Observables. We could add other things to the pipe if we wanted, but here the delay is all we need.
  • If no matching record was found:
    • It calls RxJS’s timer function to effect the delay. You might expect that we could call throwError and pipe/delay its result as in the previous case, but that does not work (details here).
    • Because timer emits an indefinite series of results, the method must mergeMap them in the pipe. However, it callsthrowError on the first one, which shuts everything down.

As I mentioned, ProduceLookupService derives from LookupService<TRecord>. In the next post of this series, we will see how those classes work together.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.