Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 365
Johannes Hoppe Avatar asked Dec 21 '16 22:12

Johannes Hoppe


1 Answers

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!

like image 150
Pascal Precht Avatar answered Sep 27 '22 21:09

Pascal Precht