茉莉花间谍程序不会覆盖模拟实现

时间:2019-01-11 16:03:21

标签: angular jasmine mocking karma-jasmine angular-test

在我正在测试的类的ngOnInit方法中,我调用了重新运行可观察对象的服务函数。我已经为该服务实现了一个模拟,但是我正在尝试为这个确切的测试用例使用间谍程序。 以我的理解,除非我在间谍上调用“ .and.callThrough()”,否则间谍将覆盖模拟实现。问题是,尽管我为该函数设置了一个间谍,但每次仍然可以执行模拟实现。

我尝试将间谍移动到没有帮助的beforeEach部分。 我也尝试使用不带“ .and.callFake()”扩展名的间谍。但这没有帮助。

spec.ts文件:

fdescribe('AppComponent', () => {
  let fixture;
  let component;
  let dataServiceMock: DataServiceMock;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      declarations: [AppComponent],
      providers: [{ provide: DataService, useClass: DataServiceMock }],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    dataServiceMock = TestBed.get(DataService);
  });


  fit('should not show navigation if not logged in', async(() => {
   spyOn(dataServiceMock,'getCurrentUser').and.callFake(() => {
     console.log('IN CALL FAKE')
     throwError(new Error('induced error'))
   });
 }));

服务模拟的实现:

export class DataServiceMock {
  currentUser: User;

  private createValidUser() {
    let validUser = new User();
    validUser.username = 'valid';
    validUser.password = 'valid';
    validUser.role = 'valid';
    this.currentUser = validUser;
  }

  public getCurrentUser(): Observable<User> {
    this.createValidUser();
    return of(this.currentUser);
  }

已测试组件的ngOnInit:

ngOnInit(): void {
  this.dataService.getCurrentUser().subscribe(user => {
    this.currentUser = user;
    console.log('received user:', this.currentUser)
  })
}

我希望控制台日志打印出“ IN CALL FAKE”并抛出“诱发错误”,但控制台却打印出“ received user:”和在服务模拟中创建的有效用户。

1 个答案:

答案 0 :(得分:1)

这只是一个计时问题。在您的beforeEach()中,您正在执行fixture.detectChanges()。这将执行ngOnInit(),有关详细信息,请参见docs。因此解决方案是不要在此处调用fixture.detectChanges(),而是在更改了getCurrentUser的收益后将其移入规范。

这是工作StackBlitz,显示此测试有效。我还更改了一些其他细节以进行工作测试:

  • 您的callFake实际上没有返回任何东西。看来您打算返回throwError(),但是由于您的组件中实际上没有任何可观察的错误处理,因此这引起了进一步的问题,因此对此进行测试是没有意义的。
  • 我添加了伪造的回报return of({username: 'test'}),只是为了允许组件.subscribe()中的ngOnInit()设置可以测试的内容-然后,我设置了一个简单的期望值,用于测试{ {1}}设置正确。
  • 我删除了围绕此规范使用的不必要的component.currentUser.username包装器-由于您使用的是同步Observable(由async()创建)进行测试,因此不需要这样做。

这是StackBlitz的新规范:

of()

我希望这会有所帮助。