1

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

1 Answer 1

3

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();
  };
}));
Sign up to request clarification or add additional context in comments.

3 Comments

thank you, maybe my examples wasn't that good. "a" is in fact the reference to a video tag and "test()" is the "onplay" function of it. So I guess I can't move the call of onplay in the zone because it's fired by the video itself right? Do I have to take "done" here or is there a solution with async/zones?
I don't know. I don't really have any experience testing video, and I'm not completely sure what you mean. If you post a real example, maybe I can play with it :-)
sorry I tried to create a plunker but couldn't get it to run. But your hint the caller also needs to be in the zone helped me understand it. At the end I just used done only and it works.

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.