1

I recently upgraded a project to Angular 6, and now tests that were working fine before are now failing. Here's an example of one of those tests:

  beforeEach(
    async(() => {
      TestBed.configureTestingModule({
        declarations: [CampaignsDetailScheduleComponent],
        imports: [
          SomeModule,
          ReactiveFormsModule,
          TranslateModule.forRoot({
            loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
          }),
          StoreModule.forRoot({})
        ],
        providers: [{ provide: ConfigService, useValue: ConfigServiceMock }],
        schemas: [NO_ERRORS_SCHEMA]
      });
      fixture = TestBed.createComponent(CampaignsDetailScheduleComponent);
      comp = fixture.componentInstance; // Component test instance
      _store = fixture.debugElement.injector.get<Store<State>>(Store);
      comp.campaignModel$ = of(CampaignMockData);
      fixture.detectChanges();
    })
  );

it(
    'close edit schedule modal',
    async(() => {
      spyOn(_store, 'dispatch');
      comp.onClose();
      const args = new ShowHideEditScheduleModal(false);
      expect(_store.dispatch).toHaveBeenCalledWith(args);
    })
  );

Pre-Angular 6, this test passed with no issues. But now under Angular 6, I get the error:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.--Pendng async tasks are: [type: macroTask, source: setInterval, args: {handleId:4072,isPeriodic:true,delay:0,args:[object Arguments],__creationTrace__:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]},type: macroTask, source: setInterval, args: {handleId:4075,isPeriodic:true,delay:0,args:[object Arguments],__creationTrace__:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]}]

Does anyone have any idea what might be going on?

7
  • I do not know if this is some Jasmine thing, but are you sure you need the async since you don't have any await ? Commented Jun 7, 2018 at 17:58
  • @Seblor In this case, async isn't the JavaScript async keyword, it's a helper function provided by Angular. Commented Jun 7, 2018 at 17:59
  • Thanks for the information. Do you have any link to the doc about that ? Commented Jun 7, 2018 at 18:00
  • This might be helpful: alligator.io/angular/testing-async-fakeasync Commented Jun 7, 2018 at 18:05
  • Have you tried this fix ? github.com/angular/protractor/issues/… Commented Jun 7, 2018 at 18:19

2 Answers 2

1

use fakeAsync instead of async in before each block.

Sign up to request clarification or add additional context in comments.

Comments

0

You can either increase the default jasmine timeout (which is 5s) interval by doing

it(
    'close edit schedule modal',
    async(() => {
      spyOn(_store, 'dispatch');
      comp.onClose();
      const args = new ShowHideEditScheduleModal(false);
      expect(_store.dispatch).toHaveBeenCalledWith(args);
   // increase default timeout interval to 10s
}), 10000);

OR you can solve it using done() method. Adding this will wait for your test to complete. I guess you cannot use async while using done()

it('close edit schedule modal', (done) => {
          spyOn(_store, 'dispatch');
          comp.onClose();
          const args = new ShowHideEditScheduleModal(false);
          expect(_store.dispatch).toHaveBeenCalledWith(args);
          done();
       // increase default timeout interval to 10s
 }, 10000);

6 Comments

Thank you for the suggestions. Unfortunately neither of these solutions seem to work in this case. :(
Ok comp.onClose(); is executed asynchronously right. Then you can simply add the code inside setTimeout(). Or if you wish to stick with async then use fixture.whenStable().then()
What's really strange is that I have other tests in other files that follow the same pattern, and those tests are passing. I have no idea what's going on here.
I was able to narrow down the problem. If I comment out the call to fixture.detectChanges() in the beforeEach call, the test passes. Not sure why, though...
Well then, you probably have something asynchronous inside ngOnInit(). Since you commented out fixture.detectChanges, your ngOnInit() was not invoked and hence your test case executed synchronously which made it pass.
|

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.