英文:
karma angular test router navigate
问题
我正在开发一个Angular练习应用程序,并使用Karma和Jasmine进行测试。我试图测试路由器的导航功能。问题是这个调用在一个then()
内部。我认为由于是异步操作,所以有些东西不起作用。错误信息是:期望spy navigate
已被调用:[ [ '/error' ] ],但它从未被调用。我该如何解决这个问题?
我的ts代码:
myFunction(): void {
functionWhichReturnsPromise().then(() => {
this.router.navigate(['/error']);
});
}
规范文件:
describe('myComponent', () => {
let component: myComponent;
let fixture: ComponentFixture<myComponent>;
let router: Router;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [myComponent],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents();
fixture = TestBed.createComponent(myComponent);
router = TestBed.inject(Router);
spyOn('functionWhichReturnsPromise').and.returnValue(Promise.resolve());
fixture.detectChanges();
});
it('should call navigate', () => {
const spyRouter = spyOn(router, 'navigate').and.resolveTo(true);
component.myFunction();
expect(spyRouter).toHaveBeenCalledWith(['/error']);
});
});
英文:
I'm developing an angular exercising app and testing it with Karma and Jasmine. I'm trying to test router's navigate functionality. The problem is that this call is inside a then(). I suppose something is not working because is async. The error: Expected spy navigate to have been called with:[ [ '/error' ] ] but it was never called. How can I resolve it?
My ts:
myFunction(): void {
functionWhichReturnsPromise().then(() => {
this.router.navigate('/error');
});
}
Spec file:
describe('myComponent', () => {
let component: myComponent;
let fixture: ComponentFixture<myComponent>;
let router: Router;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [myComponent],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents();
fixture = TestBed.createComponent(myComponent);
router = TestBed.inject(Router);
component = fixture.componentInstance;
spyOn('functionWhichReturnsPromise').and.returnValue(Promise.resolve());
fixture.detectChanges();
});
it('should call navigate', () => {
const spyRouter = spyOn(router, 'navigate').and.resolveTo(true);
component.myFunction();
expect(spyRouter).toHaveBeenCalledWith(['/error']);
});
});
答案1
得分: 1
Angular允许您通过将测试函数包装在fakeAsync
中,然后使用tick(ms)
来同步模拟异步函数的时间流逝,其中ms是您希望经过的毫秒数。
使用您的代码:
it('should call navigate', fakeAsync(() => {
const spyRouter = spyOn(router, 'navigate').and.resolveTo(true);
component.myFunction();
tick() //可能需要指定毫秒数,具体取决于'myFunction'的操作
expect(spyRouter).toHaveBeenCalledWith(['/error']);
}));
FakeAsync文档
请注意,在您的情况下,根据您的Promise的操作,flushMicrotasks()
可能也可以代替tick()
。
英文:
Angular lets you synchronously simulate the passing of time of an async function by wrapping your test function in fakeAsync
, then using tick(ms)
where ms is the number of millisecond you want ellapsed.
With your code:
it('should call navigate', fakeAsync(() => {
const spyRouter = spyOn(router, 'navigate').and.resolveTo(true);
component.myFunction();
tick() //might need to specify a number of millisecond
//depending on what 'myFunction' does
expect(spyRouter).toHaveBeenCalledWith(['/error']);
}));
FakeAsync doc
Note that in you case, depending on what your promise does, flushMicrotasks()
might also work instead of tick()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论