Тестовые случаи проходят, когда запускаются сами по себе, но не проходят при запуске в группе - jasmine


0

У меня есть несколько из следующих тестовых случаев, которые успешно выполняются при индивидуальном выполнении, но случайным образом не выполняются при выполнении в группе. Все они используют setTimeout. Они находятся в одном файле spec, разделенном на отдельные методы describe.

Например. Этот тестовый пример (который использует setTimeout) проходит, когда я запускаю его сам, но когда я запускаю его в группе, он терпит неудачу. Я подозреваю, что проблема связана с setTimeout. Я пытался использовать done, но это не решает проблему.

    describe(AppComponent Test suite, () => {

      let component: AppComponent;
      let fixture: ComponentFixture<AppComponent>;

      beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [
            AppComponent,
    ...
          ],
          imports: [
    ....
          ],
          providers: [{provide: APP_BASE_HREF, useValue: /},
....]

    }).compileComponents();
  }));


      beforeEach(() => {
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        let componentDE = fixture.debugElement;
        let componentNE:HTMLElement = componentDE.nativeElement;
        componentNE.setAttribute("signup","someIncorrectValue");
        fixture.detectChanges();
      });
      it(should show dialog message if the application has unrecognised value of signup attribute in url,(done)=>{
        spyOn(component,showDialog);
        setTimeout(()=>{
          expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
        },1000); done();
      });
    });

Представьте себе больше похожих тестов в одном файле, каждый в своем собственном describe, все с использованием setTimeout.

Почему они терпят неудачу? Если проблема заключается в синхронизации, как мне их синхронизировать?

UPDATE

Я тоже попробовал async/await, но без радости!

it(should show dialog message if the application has unrecognised value of signup attribute in url,async ()=>{
    spyOn(component,showDialog);
    await setTimeout(()=>{
      expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);

      },1000);

  });

Я также переместил вызов на done внутри обратного вызова setTimeout, но и там не было никакой радости.

it(should show dialog message if the application has unrecognised value of signup attribute in url, (done)=>{
    spyOn(component,showDialog);
     setTimeout(()=>{
      expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
      done();
      },1000);
  });

Компонент является точкой входа приложения и вызывается путем передачи атрибута signup в url.

<app-root [email protected]> 

Регистрация указывает angular при запуске, запущено ли приложение, потому что пользователь щелкнул ссылку регистрации. Соответственно, angular может показать сообщение, была ли регистрация успешной или нет. Ранее я столкнулся со следующей проблемой (При получении ошибки ExpressionChangedAfterItHasBeenCheckedError я обновляю свойство компонента из другого компонента) и, чтобы устранить его, я добавил setTimeout в ngAfterViewInit компонента приложения

ngAfterViewInit(){


    setTimeout(()=>{
      this.checkIfSignupProcess();
      this.authGuard.authGuardError$.subscribe((authGuardContext:AuthGuardContext)=>{
        this.handleAuthGuardContextMessage(authGuardContext);
      });
      this.dialogService.dialogMessage$.subscribe((message:DialogServiceMessageContext)=>{
        console.log("received message from Dialog box service");
        this.handleDialogServiceMessage(message);
      })
    },100);

    /*
    OR
    this.isSignupProcess(); //this will cause ExpressionChangedAfterItHasBeenCheckedError error s the function changes message of DialogComponent but the change detection isnt complete.
    this.cd.detectChanges();
    */
  }

ОБНОВЛЕНИЕ 2

Я пытался использовать галочку, но тест все равно не прошел, даже если он запускался индивидуально.

fit(should show dialog message if the application has unrecognised value of signup attribute in url, ()=>{
    jasmine.clock().install();
    spyOn(component,showDialog);
    setTimeout(() => {
      console.log("in spec timeout");
      expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);

    },1000);
    jasmine.clock().tick(1001);
    jasmine.clock().uninstall();
     /*setTimeout(()=>{
      expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
      done();
      },1000);*/
  });

Причиной сбоя является Expected spy showDialog to have been called with [ Unrecognised message: someIncorrectValue, Function ] but it was never called.

ОБНОВЛЕНИЕ 3

Я заметил, что хотя значение тайм-аута составляет 100 в моем компоненте и 1000 в моих спецификациях, тайм-аут спецификации истекает первым !!!

Этот код из моего компонента, который должен показывать диалоговое окно, вызывается после моего кода спецификации, даже если значение тайм-аута в компоненте равно 100 по сравнению с 10000 в спецификациях !!

тайм-аут компонента

setTimeout(()=>{
      console.log("timeout of component");
      this.checkIfSignupProcess();
    ...,100
}

Заданное время ожидания

fit(should show dialog message if the application has unrecognised value of signup attribute in url, ()=>{
    jasmine.clock().install();
    spyOn(component,showDialog);
    setTimeout(() => {
      console.log("in spec timeout 10000");
      expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);

    },10000);
    jasmine.clock().tick(10001);
    jasmine.clock().uninstall();
     /*setTimeout(()=>{
      expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
      done();
      },1000);*/
  });
Источник
  •  67
  •  2
  • 3 май 2020 2020-05-03 14:17:56

2 ответа

0

В конце я реорганизовал контрольные примеры в следующие (удалил setTimeout из спецификации и вызвал тестируемую функцию прямо из спецификации.

it(should show dialog message if the application has got error signup attribute in url, ()=>{
    spyOn(component,showDialog)
    component.checkIfSignupProcess();
    expect(component.showDialog).toHaveBeenCalledWith("Error: Signup wasnt successful",new  DialogContext());

  })
0

Не знаю, почему они терпят неудачу, но чтобы избавиться от setTimeout, вы можете попробовать объединить callThrough и callFake следующим образом:

it(should show dialog ..., (done)=>{
    spyOn(component,showDialog).and.callThrough().and.callFake(() => {
        expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
        done();
    });
});
  • 3 май 2020 2020-05-03 14:17:57