Search code examples
angularunit-testingjasminekarma-jasmine

Async function did not complete within 5000ms (Jasmine)


I am new to angular testing and I am using Jasmine as testing framework I try to test my service class but I could not know how to resolve this error I went through different examples but all showed me different errors. Is there any solution

My Service class

@Injectable({
  providedIn: 'root'
})
export class DisbursementService {
    
  private get apiUrl(): string {
    return this.appConfigService.settings?.apiUrl;
  }

  constructor(private readonly http: HttpClient, private readonly appConfigService: AppConfigService) {}

  /**
   * This function is used to call the Disbursement grid API and fetch the Disbursement details
   * @params: none
   * returns: return success/failure Disbursement object
   */
  public getAll(): Observable < DisbursementGridDto[] > {
    return this.http.get < DisbursementGridDto[] > (this.buildUrl('Disbursement/GetAll'));
  }       

  private buildUrl(functionname: string, id ? : number | string): string {
    return `${this.apiUrl}/${functionname}${id ? `/${id}` : ''}`;
  }

}

Here is my test

describe('DisbursementService', () => {
  let httpTestingController: HttpTestingController;
  let disbService: DisbursementService;

  beforeEach(waitForAsync(async () => {
    disbService = jasmine.createSpyObj(['getAll']);
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule]
    });
    httpTestingController = TestBed.inject(HttpTestingController);
    disbService = TestBed.inject(DisbursementService);
    //spyOn(disbService, 'getAll').and.returnValue(of(MockData.createDisbursementGridDtoList()));
  }));

  it('getAll should return expected data', (done) => {
    const expectedData = MockData.createDisbursementGridDtoList();

    disbService.getAll().subscribe(data => {
      expect(data.length).toEqual(expectedData.length);
      expect(data).toEqual(expectedData);
      done();
    });
  });
});

Solution

  • Try this (follow comments with !!):

    describe('DisbursementService', () => {
      let httpTestingController: HttpTestingController;
      let disbService: DisbursementService;
    
      beforeEach(waitForAsync(async () => {
        TestBed.configureTestingModule({
          imports: [HttpClientTestingModule],
          // !! provide the actual service in the TestBed here.
          providers: [DisbursementService],
        });
        httpTestingController = TestBed.inject(HttpTestingController);
        disbService = TestBed.inject(DisbursementService);
      }));
    
    
      afterEach(() => {
        // !! expect no pending Http Call
        httpTestingController.verify();
      });
    
      it('getAll should return expected data', (done) => {
        const expectedData = MockData.createDisbursementGridDtoList();
    
        disbService.getAll().subscribe(data => {
          expect(data.length).toEqual(expectedData.length);
          expect(data).toEqual(expectedData);
          done();
        });
        
        // !! Get a call on the pending request
        const req = httpTestingController.expectOne(call => call.method === 'GET');
        // !! Send this response to the pending request
        req.flush(expectedData);
      });
    });
    

    Check this link out on how to test services that send Http requests: https://testing-angular.com/testing-services/#testing-a-service-that-sends-http-requests.