Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: Expected no open requests, found 1

I am getting this error when I try to execute HTTP unit test cases.

I am using Angular 5. How can I resolve this?

Below is my code for normal GET. Below code just brings normal GET.

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController, TestRequest } from 
'@angular/common/http/testing';

import { DangerService } from './danger.service';
import { DangerFlag } from '../danger.model';


describe('DataService Tests', () => {
    let dataService: DangerService;
    let httpTestingController: HttpTestingController;

    let testDangerFlags: DangerFlag[] = [ "sample data" ]

    beforeEach(() => {
        TestBed.configureTestingModule({
        imports: [ HttpClientTestingModule ],
        providers: [ DangerService ]
    });

    dataService = TestBed.get(DangerService);
    httpTestingController = TestBed.get(HttpTestingController);
});

afterEach(() => {
    httpTestingController.verify();
});

fit('should get all danger flags', () => {
    dataService.getDangerFlagDetails()
        .subscribe((data: DangerFlag[]) => {
            expect(data.length).toBe(3);
        });
    });
});
like image 919
user1037747 Avatar asked Mar 22 '18 13:03

user1037747


2 Answers

Expected no open requests, found 1

This happens when you make a mock request, but don't 'complete/close' it. An open request may stay open after a test is run, eventually memory leaking, especially if the test is ran multiple times.

Subscribing to a mock request calls it as far as the client side is concerned but does not 'complete' it as far as the backend is concerned. 'Completing' a request can be done in a number of ways;

backend = TestBed.get(HttpTestingController)

  1. backend.expectOne(URL) - this will both test for a url, and 'close' the backend call. This will not test for params, and will fail if your query has params in it.
  2. backend.expectNone(URL) - in case you're testing for urls that have params, expectOne() wont work. You'll have to use backend.match(). Match does not auto close the backend api call, so you can expectNone() after it to close it out.
  3. .flush(RESPONSE) - flush will force-send a response for the http call, and subsequently close the call. Note: if calling flush on a match(), watch out for match returning an array, i.e. backend.match(...)[0].flush({})

Any of these methods will close out the http request, and make backend.verify() behave.

References

  • You can find in depth examples, and more explanations here
  • expectOne() and match() return an instance of TestRequest
  • expectNone() always returns void
like image 141
Pix3l Avatar answered Sep 17 '22 02:09

Pix3l


If a test is async, you have to tell jasmine that it is async and when it is finished.

it('should get all danger flags', (done) =>{^
                                   ^^^^^^
    dataService.getDangerFlagDetails()
         .subscribe((data: DangerFlag[]) =>{
              expect(data.length).toBe(3);
              done();
              ^^^^^^
         });
});

You do that by calling a function that jasmine will provide when running a test as parameter.

like image 37
Leon Avatar answered Sep 18 '22 02:09

Leon