5

I am using Jasmine & Karma for unit testing angular app . I have wrote unit tests like this:

describe('#getAll', async () => {
    it('#should return user intergration_tester', inject([UsersService], async(service: UsersService) => {
        await service.getAll('integration_tester', access_token).subscribe(
            user => {
                expect(user[0].firstName).toContain('Integration');
                done();
            })
      }));

      it('#should return error 404', inject([UsersService], (service: UsersService) => {
        service.getAll('integration_tester', '').subscribe(
            user => {expect(user[0].firstName).not.toContain('Integration');},
            err => { expect(err).toContain('error');}
        )
      }));
})

When I execute test cases , I see a message SPEC HAS NO EXPECTATIONS for both test cases . I am wondering why it shows spec has no expectations.

Then I followed the suggested solutions in this post: Spec has no expectations - Jasmine testing the callback function

Using done():

describe('#getAll', async () => {
    it('#should return user intergration_tester', inject([UsersService], async(service: UsersService, done) => {
        await service.getAll('integration_tester', access_token).subscribe(
            user => {
                expect(user[0].firstName).toContain('Integration');
                done();
            })
      }));

      it('#should return error 404', inject([UsersService], (service: UsersService, done) => {
        service.getAll('integration_tester', '').subscribe(
            user => {expect(user[0].firstName).not.toContain('Integration'); done();},
            err => { expect(err).toContain('error'); done();}
        )
      }));
})

Again, Jasmine tells me that the spec has no expectations

Ha Bardan
  • 125
  • 1
  • 3
  • 8

1 Answers1

3

Awaiting a subscription doesn't do anything...

await service.getAll(...).subscribe(...)

You need to convert the observable to a Promise. Also, make sure your observable completes, otherwise you need to get only the first element or the promise will never resolve (let's say that getAll continues to send events or something - but you should get a timeout during the running of the tests). This should do the trick:

describe('#getAll', async () => {
    it('#should return user intergration_tester', inject([UsersService], async (service: UsersService) => {
        const user = await service.getAll('integration_tester', access_token).toPromise();
        expect(user[0].firstName).toContain('Integration');
    }));

    it('#should return error 404', inject([UsersService], async (service: UsersService) => {
        try {
            const user = await service.getAll('integration_tester', '').toPromise();

            expect(user[0].firstName).not.toContain('Integration');
        } catch (err) {
            // why do you also expect an error to be thrown?
            expect(err).toContain('error');
        }
    }));
})
Andrei Tătar
  • 7,872
  • 19
  • 37
  • 1
    Thanks for help. Now I have the following error message: Error: Timeout - Async callback was not invoked. The service send a request to a real server. Do you think the problem is related to that? – Ha Bardan Feb 28 '19 at 09:27
  • Does `service.getAll` return a one event observable? Meaning it emits an event and completes (like the HttpClient service)? If so, you need to check how much the actual request takes. I think the default timeout is 2000 msec. If your request takes longer than that, the test runner will fail so you need to increase the timeout. Also, check if `inject` actually calls your code (add console.log or something). – Andrei Tătar Feb 28 '19 at 09:29
  • Thank you for helping. I imported HttpClientTestingModule instead of the HttpClientModule. That was my mistake. – Ha Bardan Feb 28 '19 at 11:26
  • @AndreiTătar your solution works, but I am still getting the warning "SPECT HAS NO EXPECTATIONS"? didn't have any error, and was sure the line where the "Expect" is has gone over by the compiler. – roger May 21 '19 at 02:27