NGXS操作可观察的Jest期望



我目前正面临一个奇怪的行为。当我想在成功完成store Action后对商店状态运行多个期望时,我无法观察到测试失败的原因。

如果满足了所有期望,则测试将成功运行(请参阅下面的控制台日志(。在断言失败的情况下,done回调永远不会被调用,预期的错误也不会被抛出给测试运行程序。(请参阅下面的控制台日志-超时(。

作为参考测试,我创建了一个Subject,并将其与next一起调用。一切如预期!这似乎是来自'@ngxs/store'Actions的问题。

是否存在已知问题?我是否以错误的方式使用Actions提供程序?

我的设置详细信息:

➜ npx envinfo --system --npmPackages                                 
System:
OS: macOS 12.0.1
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 3.02 GB / 32.00 GB
Shell: 5.8 - /bin/zsh
npmPackages:
@angular-devkit/build-angular: ~12.2.1 => 12.2.1 
@angular-devkit/build-webpack: ^0.1202.1 => 0.1202.1 
@angular-eslint/builder: ~12.2.1 => 12.2.2 
@angular-eslint/eslint-plugin: ~12.2.1 => 12.2.2 
@angular-eslint/eslint-plugin-template: ~12.2.1 => 12.2.2 
@angular-eslint/schematics: ~12.6.1 => 12.6.1 
@angular-eslint/template-parser: ~12.2.1 => 12.2.2 
@angular/animations: ~12.2.1 => 12.2.1 
@angular/cdk: ~12.2.1 => 12.2.1 
@angular/cli: ~12.2.1 => 12.2.1 
@angular/common: ~12.2.1 => 12.2.1 
@angular/compiler: ~12.2.1 => 12.2.1 
@angular/compiler-cli: ~12.2.1 => 12.2.1 
@angular/core: ~12.2.1 => 12.2.1 
@angular/flex-layout: ^12.0.0-beta.34 => 12.0.0-beta.34 
@angular/forms: ~12.2.1 => 12.2.1 
@angular/localize: ^12.2.1 => 12.2.1 
@angular/platform-browser: ~12.2.1 => 12.2.1 
@angular/platform-browser-dynamic: ~12.2.1 => 12.2.1 
@angular/router: ~12.2.1 => 12.2.1 
@ngxs/store: ^3.7.3 => 3.7.3 
@types/crypto-js: ^4.0.2 => 4.0.2 
@types/jest: ^27.0.3 => 27.0.3 
@types/node: ^12.11.1 => 12.20.15 
@typescript-eslint/eslint-plugin: ^4.23.0 => 4.23.0 
@typescript-eslint/parser: ^4.23.0 => 4.23.0 
eslint: ^7.26.0 => 7.29.0 
eslint-config-prettier: ^8.3.0 => 8.3.0 
eslint-plugin-prettier: ^3.4.0 => 3.4.0 
husky: ^7.0.4 => 7.0.4 
jest: ^27.4.3 => 27.4.3 
jest-preset-angular: ^11.0.1 => 11.0.1 
prettier: ^2.3.2 => 2.3.2 
prettier-eslint: ^12.0.0 => 12.0.0 
rxjs: ~6.6.0 => 6.6.7 
tslib: ^2.1.0 => 2.3.0 
typescript: ~4.2.3 => 4.2.4 
zone.js: ~0.11.4 => 0.11.4 

代码示例:

import { TestBed } from '@angular/core/testing';
import { Actions, NgxsModule, ofActionCompleted, Store } from '@ngxs/store';
describe('Review Task Store', () => {
let store: Store;
let actions$: Actions;
beforeEach(() => {
TestBed.configureTestingModule({ imports: [NgxsModule.forRoot([TestState])] });
store = TestBed.inject(Store);
actions$ = TestBed.inject(Actions);
});
it('should example', (done) => {
// Arrange
actions$
.pipe(ofActionCompleted(ExampleAction))
.subscribe(() => {
// Assert
console.log('i was here! Before');
expect(true).toBeFalsy();
console.log('i was here! After');
done();
});
// Act
store.dispatch(new ExampleAction());
});
});

快乐案例日志:

console.log
i was here! Before
console.log
i was here! After

不愉快的案例日志:

console.log
i was here! Before

: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.
Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error: 
[...]

一个可能的解决方案是将断言移动到管道的一个步骤,并添加一个catchError以显示包含的所有错误。

但它会生成一些样板代码:/

it('should show expectation error', (done) => {
// Arrange
const assertFn = (actionUnderTest) => {
// Assert
console.log('ACTION$ -> i was here! Before');
expect(true).toBeFalsy();
console.log('ACTION$ -> i was here! After');
done();
}
actions$
.pipe(
ofActionCompleted(ExampleAction),
tap(assertFn),
catchError((err, caught) => {
done.fail(err)
return caught;
})
)
.subscribe();
// Act
store.dispatch(new ExampleAction(testValue));
});

最新更新