簡體   English   中英

當單獨運行時,測試用例通過,但在組中運行時,則失敗

[英]Test cases passes when run by itself but fails when run in a group

我有以下幾個測試用例,它們在單獨執行時可以成功運行,但是在分組運行時會隨機失敗。 他們都使用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);

  });

我也將調用移到setTimeout的回調內done但那里也沒有樂趣。

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);
  });

該組件是應用程序的入口點,並通過在url傳遞一個signup屬性來調用。

<app-root signup=@signup> 

注冊會在啟動時告知Angle,因為用戶單擊了注冊鏈接,該應用是否已啟動。 因此,角度可以顯示注冊成功與否的消息。 早些時候,我遇到以下問題( 從另一個組件更新一個組件的屬性時出現ExpressionChangedAfterItHasBeenCheckedError錯誤 )並解決該問題,我在應用程序組件的ngAfterViewInit中添加了setTimeout

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

我嘗試使用“ tick”,但即使單獨運行,測試仍然失敗。

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);*/
  });

不知道為什么它們會失敗,但是為了擺脫setTimeout ,您可以嘗試將callThroughcallFake組合如下:

it('should show dialog ...', (done)=>{
    spyOn(component,'showDialog').and.callThrough().and.callFake(() => {
        expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
        done();
    });
});

最后,我將測試用例重新組織為以下內容(從規范中刪除了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(''));

  })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM