user2170547
user2170547

Reputation: 361

Angular 2 Testing: What's the correct way for async testing?

I have the following test in an angular 2 project with karma and jasmine:

let a: any;

beforeEach(() => {
    a = {};

    setTimeout(() => {
        a.test();
    }, 1000);
});

it('should work with async and promise', async(() => {

   return new Promise((resolve) => {
       a.test = () => {
           console.log('erster test');
           assertThat(true, is(false));
           resolve();
       };
   });
}));

it('should work with async and done', async((done) => {

    a.test = () => {
        console.log('zweiter test');
        assertThat(true, is(false));
        done();
    };
}));

it('should work with done', (done) => {

    a.test = () => {
        console.log('dritter test');
        assertThat(true, is(false));
        done();
    };
});

The only case that works (means it fails) is the last one with just a "done" callback. With the second one I'm not sure but shouldn't the first one be the correct way to test async in angular 2? I thought with "async" you place a zone around your function and it's waiting for the returned promise? I tried to make sense of the async implementation but I'm not getting it: https://github.com/angular/angular/blob/master/modules/%40angular/core/testing/async.ts

Upvotes: 1

Views: 1115

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 209012

The zone gets created inside the async method. So your setTimeout (in the beforeEach) is not inside that zone. If you move the setTimeout to inside the async callback, then it is in the zone, and the tests should work as expected (meaning wait for the asynchronous tasks to complete).

it('should work with async and promise', async(() => {
  setTimeout(() => {
    a.test();
  }, 1000);
  return new Promise((resolve) => {
    a.test = () => {
      console.log('erster test');
      expect(true).toBe(false);
      resolve();
    };
  });
}));

it('should work with async and done', async((done: Function) => {
  setTimeout(() => {
    a.test();
  }, 1000);
  a.test = () => {
    console.log('zweiter test');
    expect(true).toBe(false);
    done();
  };
}));

Upvotes: 3

Related Questions