Angular with Jasmine: is there a conflict between asynchronous in beforeEach () and async in it ()?

My goal is to test API calls, taking into account delays. I was inspired by this post .

I developed a sandbox in which the API layout takes 1000 ms to respond and change the value of a global variable result. The test checks the value after 500 ms and after 1500 ms.

Here is the code where the last test is supposed to be:

    let result: number;

    const mockAPICall = (delay: number): Observable<number> => {
        console.log('API called');
        return Observable.of(5).delay(delay);
    };

    beforeEach(() => {
        console.log('before each');
    });

    it('time test', async(() => {
        result = 0;
        const delay = 1000;
        console.log('start');

        mockAPICall(delay).subscribe((apiResult: number) => {
            console.log('obs done');
            result = apiResult;
        });

        console.log('first check');
        expect(result).toEqual(0);

        setTimeout(() => {
                console.log('second check');
                expect(result).toEqual(0);
            }, 500
        );

        setTimeout(() => {
                console.log('third check');
                expect(result).toEqual(0);
            }, 1500
        );
    }));

The final test does not work as expected, and I get this in the logs:

before each
API called
first check
second check
obs done
third check

Now, if I put async()in beforeEach():

    beforeEach(async(() => {
        console.log('async before each');
    }));

the test passes, and I only get this in the logs:

async before each
API called
first check

I did not expect this. Why is this behavior? What is going on behind the scenes?

: async() beforeEach(), testBed compileComponents.

+6
1

Angular .

done() , async fakeAsync. . , async fakeAsync , intervalTimer() RxJS delay().

rxjs, , TestSchedulers rxjs, (, delay).

, delay, done(), Jasmine.

let result: number;

const mockAPICall = (delay: number): Observable<number> => {
    console.log('API called');
    return Observable.of(0).delay(delay); // changed from 5 -> 0, to make tests pass
};

beforeEach(async(() => {
    console.log('async before each');
}));

it('time test', done => async(() => {
    result = 0;
    const delay = 1000;
    console.log('start');

    mockAPICall(delay).subscribe((apiResult: number) => {
        console.log('obs done');
        result = apiResult;
    });

    console.log('first check');
    expect(result).toEqual(0);

    setTimeout(() => {
            console.log('second check');
            expect(result).toEqual(0);
        }, 500
    );

    setTimeout(() => {
            console.log('third check');
            expect(result).toEqual(0);
            done(); // indicate that the test is complete
        }, 1500
    );
})());

delay async, "" - , .

+1

All Articles