5

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?

3
  • Altering passing tests and having them still pass isn't necessarily useful - what happens if you take a failing test using async and remove that call? Does it still fail? Commented Dec 21, 2016 at 22:51
  • first example is basically wrong, expect("THIS TEST IS FALSE POSITIVE").toEqual(false); should never be green. it would work, if the code would run async. but it does not (anymore). Commented Dec 21, 2016 at 23:00
  • I propose that the mockResponse is synchronous, but MockConnection does not seem to be synchronous. I added a second test to each test (reducing it to 2 videos, and the synchronous one failed and the async passed. Commented Jun 30, 2017 at 13:10

1 Answer 1

6

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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.