DEV Community

loading...

TDD in Angular - Basics of HTTP Testing

Bearded JavaScripter
Full Stack Web Developer interested in readable, maintainable, composable software. Constantly (L)earning. Your code is a reflection of yourself.
・3 min read

It won't be much of a Web Application if it doesn't make HTTP requests, does it? However, it's easy to forget that these need to be tested as well!

In this article, I'll cover how to unit test HTTP requests in your Angular Application so you can have the confidence that they'll always work as expected.

Code for the article can be found here.

Setting up our code

Let's say that our HTTP calls live in a service that handles to-do items. We can do our basic CRUD operations: getting our to-do items or a single one, creating new items, updating or deleting items.

I'll be using JSONPlaceHolder for this since it's the quickest way to get started. The most barebones CRUD service should look like this:

After importing HttpClientTestingModule, the auto-generated spec file should look like this:

At this point your only test ("it should be created") should be passing.

HTTP Testing Method

Remember that during testing, we're not actually making any requests. We're only concerned with if the request was sent and if a response is handled properly when it returns. Anything that happens in between that is out of the scope of unit testing.

Therefore, let's say that we're unit testing a GET request, we only care that the request is sent and, if the request is successful, some data comes back.

Keep in mind that Angular HttpClient uses Observables rather than promises so we have to adjust our tests accordingly!

Angular provides an entire module to help us test HTTP Requests called the HttpClientTestingModule that allows us to:

  • Mock a request
  • Create a fake request with any status code
  • Pass along a response with fake data
  • Cancel a request
  • And much much more!

This means we can test our requests from every angle possible and have our application handle as much cases as possible. I'll cover these in future articles. Let's get set up!

Setting up HTTP Mocks

We need to establish a Mock network that allows us to control when requests are sent, what data is returned and whether or not the request was successful. This comes in the form of HttpTestingController as seen below:

Notice that in the afterEach block, we called httpMock.verify(). This ensures that there are no pending requests in our mock network before moving on to other tests.

Now we can really start testing our code!

Testing Requests

We want to test getSingleTodo. Based on the function name, we can expect that the HTTP response will contain a todo object. Let's represent our expectations as tests.

In the above code, we:

  • ran our getSingleTodo function and expected the result to be defined
  • used the controller to expect a request to have the URL https://jsonplaceholder.typicode.com/todos/1
  • expected the request to be a GET request
  • used the controller to manually send the request with the fake todo data.

Under normal circumstances, the getSingleTodo function would have made an actual request but our HttpTestingController intercepted the request and returned the fake data using testRequest.flush.

We can now use this information to test POST requests. These contain a request body and can return data along with the status code.

This test ensures a POST request is sent to the correct URL and the created data is returned.

Conclusion

In this article, we learned:

  • the theory behind testing HTTP requests by using a mock network
  • setting up the mock network using HttpTestingController
  • running fake requests and testing their URLs, methods and return values

The next article will show how to control fake requests so we can test our application in the event of unauthorized requests, server crashes and basic error handling.

Hope you enjoyed reading! 😄

Discussion (0)