JW.*_*JW. 11 unit-testing angular-material angular
Angular Material 提供了用于测试的组件线束,它允许您通过awaiting 承诺与它们的组件进行交互,如下所示:
it('should click button', async () => {
const matButton = await loader.getHarness(MatButtonHarness);
await matButton.click();
expect(...);
});
Run Code Online (Sandbox Code Playgroud)
但是如果按钮点击触发延迟操作呢?通常我会使用fakeAsync()/tick()来处理它:
it('should click button', fakeAsync(() => {
mockService.load.and.returnValue(of(mockResults).pipe(delay(1000)));
// click button
tick(1000);
fixture.detectChanges();
expect(...);
}));
Run Code Online (Sandbox Code Playgroud)
但是有什么办法可以在同一个测试中同时做这两项吗?
将async函数包装在里面fakeAsync()给了我“错误:代码应该在 fakeAsync 区域中运行以调用这个函数”,大概是因为一旦它完成了await,它就不再是我传递给 的同一个函数fakeAsync()。
我是否需要做这样的事情——在等待之后启动一个 fakeAsync 函数?或者有更优雅的方式吗?
it('should click button', async () => {
mockService.load.and.returnValue(of(mockResults).pipe(delay(1000)));
const matButton = await loader.getHarness(MatButtonHarness);
fakeAsync(async () => {
// not awaiting click here, so I can tick() first
const click = matButton.click();
tick(1000);
fixture.detectChanges();
await click;
expect(...);
})();
});
Run Code Online (Sandbox Code Playgroud)
Ale*_*hko 18
fakeAsync(async () => {...})是一个有效的构造。
而且,Angular Material 团队正在明确测试这种场景。
it('should wait for async operation to complete in fakeAsync test', fakeAsync(async () => {
const asyncCounter = await harness.asyncCounter();
expect(await asyncCounter.text()).toBe('5');
await harness.increaseCounter(3);
expect(await asyncCounter.text()).toBe('8');
}));
Run Code Online (Sandbox Code Playgroud)
从 Angular 12 更新到 14 后,之前运行没有问题的测试开始失败。失败的具体测试取决于fakeAsync和async。
我的案例的解决方案是将以下内容添加target到tsconfig.spec.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"module": "CommonJs",
"target": "ES2016", // Resolved fakeAsync + async tests errors
"types": ["jest"]
},
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}
Run Code Online (Sandbox Code Playgroud)
一个人为的测试示例:
it('should load button with exact text', fakeAsync(async () => {
const buttons = await loader.getAllHarnesses(
MatButtonHarness.with({ text: 'Testing Button' })
);
tick(1000);
expect(buttons.length).toBe(1);
expect(await buttons[0].getText()).toBe('Testing Button');
}));
Run Code Online (Sandbox Code Playgroud)
我收到以下错误,它直接指向tick(1000):
代码应该在 fakeAsync 区域中运行来调用此函数
ES2016将目标添加到我的所有问题后都tsconfig.spec.json得到解决。
我使用 Jest,因此使用其他测试运行程序的人可能没有相同的分辨率。