NGXS Actions Observable Jest 期望

NGXS Actions Observable Jest Expectation

我目前面临着一种奇怪的行为。 当我想 运行 在成功完成存储操作后对存储状态有多个期望时,我无法观察到测试失败的原因。

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

作为参考测试,我创建了一个 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));
    });