Angular: Testing HTTP with MockBackend, is async() really required?

949 views Asked by At

I'm using MockBackend to test code that depends in @angular/http.
All the examples around the web use an asynchronous test setup, like here:
thoughtram: Testing Services with Http in Angular

describe('getVideos()', () => {

  it('should return an Observable<Array<Video>>',
      async(inject([VideoService, MockBackend], (videoService, mockBackend) => {

      videoService.getVideos().subscribe((videos) => {
        expect(videos.length).toBe(4);
        expect(videos[0].name).toEqual('Video 0');
        expect(videos[1].name).toEqual('Video 1');
        expect(videos[2].name).toEqual('Video 2');
        expect(videos[3].name).toEqual('Video 3');

        expect("THIS TEST IS FALSE POSITIVE").toEqual(false); 
      });

      const mockResponse = {
        data: [
          { id: 0, name: 'Video 0' },
          { id: 1, name: 'Video 1' },
          { id: 2, name: 'Video 2' },
          { id: 3, name: 'Video 3' }
        ]
      };

      mockBackend.connections.subscribe((connection) => {
        connection.mockRespond(new Response(new ResponseOptions({
          body: JSON.stringify(mockResponse)
        })));
      });
  })));
});

However, I tried that out and I’m pretty sure that MockBackend executes completely synchronous:

describe('getVideos()', () => {

  it('should return an Observable<Array<Video>>',
    inject([VideoService, MockBackend], (videoService, mockBackend) => {

      const mockResponse = {
        data: [
          { id: 0, name: 'Video 0' },
          { id: 1, name: 'Video 1' },
          { id: 2, name: 'Video 2' },
          { id: 3, name: 'Video 3' },
        ]
      };

      mockBackend.connections.subscribe((connection) => {
        connection.mockRespond(new Response(new ResponseOptions({
          body: JSON.stringify(mockResponse)
        })));
      });

      let videos;
      videoService.getVideos().subscribe(v => videos = v);

      // synchronous code!?
      expect(videos.length).toBe(4);
      expect(videos[0].name).toEqual('Video 0');
      expect(videos[1].name).toEqual('Video 1');
      expect(videos[2].name).toEqual('Video 2');
      expect(videos[3].name).toEqual('Video 3');
    }));
});

I created a full example on plunker here: https://plnkr.co/edit/I3N9zL?p=preview

enter image description here

Something must have been changed since those articles were written. Can somebody point me to that breaking change? Or did I missed an important fact?

1

There are 1 answers

0
Pascal Precht On BEST ANSWER

you're completely right with your assumption, that MockConnection.mockRespond() emits synchronous. async() is not needed in this particular test.

I'm the author of the article you've referred to in your question and I've updated it accordingly.

Thank you so much for pointing this out!