Skip to content
tezvyn:

How do you mock an async service call in an Angular component test?

Source: angular.devMediumHow cards are made

How do you mock an async service call in an Angular component test?

This tests Angular unit isolation and HTTP mocking. A strong answer covers HttpTestingController setup, flushing a mock response, asserting UI changes, and notes mocking avoids flaky networks. Red flag: using real HTTP calls in unit tests.

What's really being asked

This question evaluates whether you understand test isolation and deterministic control over asynchronous dependencies in Angular. The interviewer cares if you know how to decouple a component from real network behavior and whether you grasp the difference between shallow unit tests and full integration tests. They also want to see that you understand how Angular's testing utilities replace the real HTTP backend with a controllable test harness.

The full answer

First, the candidate should mention two valid strategies. The first strategy is to override the injected service in TestBed providers with a fake stub object that returns a cold Observable or Promise. The second strategy is to keep the real service but replace the HTTP backend by importing provideHttpClientTesting and using HttpTestingController to intercept outgoing calls. Second, the candidate should walk through the flush pattern in order: trigger the component action that initiates the request, use httpTesting.expectOne to capture the pending request and assert its method or URL, call req.flush with a mock payload to synchronously complete the response, and then assert that the component state or template updates correctly. Third, the candidate should explain why mocking is crucial: it eliminates flaky network latency, prevents tests from failing when the backend is unavailable, allows simulation of error conditions like timeouts or 500 responses, and keeps test execution fast. Fourth, a complete answer mentions calling httpTesting.verify at the end of the test to ensure no unexpected requests were made.

The mistakes people make

One red flag is suggesting that component unit tests should make real HTTP calls to a live server. Another is manually managing asynchronous timing with setTimeout or JavaScript done callbacks instead of leveraging Angular's fakeAsync or waitForAsync test utilities. Some candidates forget to call flush which leaves Observables hanging and causes the test to fail with timeouts. Others call verify before the request has actually been issued, or they provide the real HttpClient without provideHttpClientTesting and then wonder why network calls leak out.

What usually comes next

The interviewer may ask how you would simulate an error response, which you do by calling req.flush with an error payload and an explicit status code such as 404 or 500. They might ask how to handle tests that fire multiple requests, where you use expectOne for each distinct endpoint or use match to handle dynamic query parameters. Another common follow-up is how you test a service method that returns an Observable which emits multiple values over time, or how you would structure tests when the component uses signals that react to the HTTP response.

A concrete example

Imagine a ProfileComponent that calls ProfileService.loadProfile which internally performs an HTTP GET to api/profile. In the test module setup you include provideHttpClient followed by provideHttpClientTesting. You inject HttpTestingController, trigger the component lifecycle, then capture the pending request using httpTesting.expectOne with the URL api/profile. You assert that req.request.method equals GET, then call req.flush with a mock profile object. After flushing, you assert that the component property bound to the template now contains the mock data and that the view renders the expected text. You finish with httpTesting.verify to confirm no additional requests escaped the test.

Interview question

In an Angular component test using HttpTestingController, what is the correct order of operations after triggering the action that initiates an HTTP request?

  • a.Call httpTesting.verify, then expectOne, then flush the mock response
  • b.Call expectOne to capture the request, flush the mock response, assert UI updates, then call verifyCorrect
  • c.Call expectOne, call verify, then flush the mock response
  • d.Provide the real HttpClient, trigger the request, and assert after a setTimeout delay
Why?

The correct flow is to intercept the request with expectOne, synchronously complete it with flush, assert the UI updates, and finally call verify to ensure no unexpected requests leaked. The most tempting distractor places verify before flush because beginners often mistake verify for a prerequisite setup step rather than a final safety check.

Just read this? Test yourself on what you have been reading.

Read the original → angular.dev

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on angular — each one lists the topics its interview covers.

See open roles