Вопрос:

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

jasmine angular6 karma-jasmine angular-testing

23 просмотра

2 ответа

4333 Репутация автора

У меня есть несколько из следующих тестовых случаев, которые успешно выполняются при индивидуальном выполнении, но случайным образом не выполняются при выполнении в группе. Они все используют 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.

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

ОБНОВИТЬ

Я пытался 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 signup=@signup> 

При запуске приложение 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 isn't 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's 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's 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);*/
  });
Автор: Manu Chadha Источник Размещён: 11.08.2019 07:43

Ответы (2)


0 плюса

253 Репутация автора

Не знаю, почему они терпят неудачу, но чтобы избавиться от них 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();
    });
});
Автор: uminder Размещён: 11.08.2019 08:09

0 плюса

4333 Репутация автора

В конце я реорганизовал контрольные примеры в следующие (удалены 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 wasn't successful",new  DialogContext(''));

  })
Автор: Manu Chadha Размещён: 12.08.2019 03:59
Вопросы из категории :
32x32