gpt4 book ai didi

angular - Jasmine spy 没有覆盖模拟实现

转载 作者:行者123 更新时间:2023-12-04 13:20:09 24 4
gpt4 key购买 nike

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

我尝试将 spy 移动到 beforeEach 部分,但没有帮助。我还尝试使用没有“.and.callFake()”扩展名的 spy 。但这没有帮助。

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:”和在服务 mock 中创建的 validUser。

最佳答案

这只是一个时间问题。在您的 beforeEach() 中,您正在执行 fixture.detectChanges()。这会执行 ngOnInit(),请参阅 docs了解详情。所以解决方案是不要在那里调用 fixture.detectChanges(),而是在更改 getCurrentUser 的返回值后将其移至规范中。

这是一个有效的 StackBlitz显示此测试有效。我还更改了更多细节以获得工作测试:

  • 你的 callFake 实际上没有返回任何东西。看起来您打算返回 throwError(),但这导致了进一步的问题,因为您的组件中实际上没有任何 Observable 错误处理,因此对此进行测试毫无意义。
  • 我添加了一个假的 return return of({username: 'test'}) 只是为了允许组件的 ngOnInit() 中的 .subscribe() 来设置一些可以测试的东西——然后我设置了一个简单的期望来测试 component.currentUser.username 是否设置正确。
  • 我删除了围绕此规范的不必要的 async() 包装器 - 因为您正在使用同步 Observables(使用 of() 创建)进行测试,所以没有需要这个。

这是 StackBlitz 的新规范:

it('should not show navigation if not logged in', () => {
spyOn(dataServiceMock,'getCurrentUser').and.callFake(() => {
console.log('IN CALL FAKE')
// throwError(new Error('induced error'))
return of({username: 'test'})
});
fixture.detectChanges();
expect(component.currentUser.username).toEqual('test');
});

希望对您有所帮助。

关于angular - Jasmine spy 没有覆盖模拟实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54150048/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com