Jasmine 测试用例单独运行时通过,但在组中运行时失败

Jasmine 测试用例单独运行时通过,但在组中运行时失败,jasmine,angular6,karma-jasmine,angular-test,Jasmine,Angular6,Karma Jasmine,Angular Test,我有以下几个测试用例,它们在单独执行时成功运行,但在组中运行时随机失败。它们都使用setTimeout。它们在单个spec文件中,在单独的description方法中分离 这个测试用例(使用setTimeout)在我单独运行时通过,但在组中运行时失败。我怀疑这个问题与setTimeout有关。我尝试使用done,但这并不能解决问题 describe('AppComponent Test suite', () => { let component: AppCompone

我有以下几个测试用例,它们在单独执行时成功运行,但在组中运行时随机失败。它们都使用
setTimeout
。它们在单个
spec
文件中,在单独的
description
方法中分离

这个测试用例(使用
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();
      });
    });
我还将调用移到了
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> 
更新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);*/
  });
失败的原因是
预期spy showDialog已使用['Unrecogned message:someIncorrectValue',Function]调用,但从未调用过它。

更新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(()=>{
      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
,您可以尝试将
callThrough
callFake
组合起来,如下所示:

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(''));

  })

有更好的方法可以在不使用
setTimeout
的情况下进行
async
测试。另外,请检查
tick
。您也可以共享组件代码吗?您不应该像以前那样执行
setTimeout
。谢谢Amit,Shashank。在问题中添加了更多信息。Shashank-尝试了
tick
,但是测试可以即使我单独运行se,它也会失败