Angular 测试预期间谍 navigateByUrl 已被调用 0 次。它被调用了 1 次
Angular testing Expected spy navigateByUrl to have been called 0 times. It was called 1 times
我在使用 Karma/Jasmine.
测试基于 Angular RxJS 的函数时有一个奇怪的行为
我有这个测试:
describe('LoginComponent', () => {
let fixture: ComponentFixture<LoginComponent>;
let component: LoginComponent;
let debugElement: DebugElement;
let location: Location;
let router: Router;
let authServiceSpy: AuthService = {
login: () => null,
user: new BehaviorSubject<UserInterface>(null)
} as jasmine.SpyObj<any>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
RouterTestingModule,
AppModule,
],
providers: [
{ provide: AuthService, useValue: authServiceSpy },
],
declarations: [
LoginComponent,
]
})
.compileComponents()
.then(() => {
router = TestBed.inject(Router);
location = TestBed.inject(Location);
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
});
describe('submit form', () => {
it('should navigate to dashboard with correct credentials', fakeAsync(() => {
spyOn(authServiceSpy, 'login').and.returnValue(of(new User()));
const navSpy = spyOn(router, 'navigateByUrl');
const button = debugElement.queryAll(By.css('.login-button'));
fixture.detectChanges();
fixture.whenStable().then(() => {
button[0].nativeElement.click();
tick();
expect(navSpy).toHaveBeenCalledTimes(1);
expect(navSpy).toHaveBeenCalledWith('/dashboard');
});
}));
it('should show error with incorrect credentials', fakeAsync(() => {
spyOn(authServiceSpy, 'login').and.returnValue(throwError('login failed'));
const navSpy = spyOn(router, 'navigateByUrl');
const button = debugElement.queryAll(By.css('.login-button'));
fixture.detectChanges();
fixture.whenStable().then(() => {
button[0].nativeElement.click();
tick();
fixture.detectChanges();
expect(navSpy).toHaveBeenCalledTimes(0);
});
}));
});
});
经过 运行 这些测试后,我收到此错误消息:
Error: 1 timer(s) still in the queue.
然后我添加 flush()
作为两个 it()
函数的开始。我得到这个错误:
Expected spy navigateByUrl to have been called 0 times. It was called 1 times.
我也尝试使用 discardPeriodicTasks()
和 flushMicrotasks()
。但没有帮助。
当我将 it()
功能与 fit()
一个接一个地使用时,一切正常。
知道如何解决这个问题吗?
正如@rmjoia所指出的,您需要重置间谍对象,因为它将在相关测试规范中重复使用。
可以通过 reset method.
来完成重置
navSpy.calls.reset
我建议在 beforeEach
函数上执行此操作。
另一个解决方案是将测试分成两个测试套件
我在使用 Karma/Jasmine.
测试基于 Angular RxJS 的函数时有一个奇怪的行为我有这个测试:
describe('LoginComponent', () => {
let fixture: ComponentFixture<LoginComponent>;
let component: LoginComponent;
let debugElement: DebugElement;
let location: Location;
let router: Router;
let authServiceSpy: AuthService = {
login: () => null,
user: new BehaviorSubject<UserInterface>(null)
} as jasmine.SpyObj<any>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
RouterTestingModule,
AppModule,
],
providers: [
{ provide: AuthService, useValue: authServiceSpy },
],
declarations: [
LoginComponent,
]
})
.compileComponents()
.then(() => {
router = TestBed.inject(Router);
location = TestBed.inject(Location);
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
});
describe('submit form', () => {
it('should navigate to dashboard with correct credentials', fakeAsync(() => {
spyOn(authServiceSpy, 'login').and.returnValue(of(new User()));
const navSpy = spyOn(router, 'navigateByUrl');
const button = debugElement.queryAll(By.css('.login-button'));
fixture.detectChanges();
fixture.whenStable().then(() => {
button[0].nativeElement.click();
tick();
expect(navSpy).toHaveBeenCalledTimes(1);
expect(navSpy).toHaveBeenCalledWith('/dashboard');
});
}));
it('should show error with incorrect credentials', fakeAsync(() => {
spyOn(authServiceSpy, 'login').and.returnValue(throwError('login failed'));
const navSpy = spyOn(router, 'navigateByUrl');
const button = debugElement.queryAll(By.css('.login-button'));
fixture.detectChanges();
fixture.whenStable().then(() => {
button[0].nativeElement.click();
tick();
fixture.detectChanges();
expect(navSpy).toHaveBeenCalledTimes(0);
});
}));
});
});
经过 运行 这些测试后,我收到此错误消息:
Error: 1 timer(s) still in the queue.
然后我添加 flush()
作为两个 it()
函数的开始。我得到这个错误:
Expected spy navigateByUrl to have been called 0 times. It was called 1 times.
我也尝试使用 discardPeriodicTasks()
和 flushMicrotasks()
。但没有帮助。
当我将 it()
功能与 fit()
一个接一个地使用时,一切正常。
知道如何解决这个问题吗?
正如@rmjoia所指出的,您需要重置间谍对象,因为它将在相关测试规范中重复使用。 可以通过 reset method.
来完成重置navSpy.calls.reset
我建议在 beforeEach
函数上执行此操作。
另一个解决方案是将测试分成两个测试套件