NGXS:如何测试一个动作是否被分派?

Fra*_*ina 11 unit-testing angular ngxs

如何单元测试一个动作是否被分派?

例如,在 LogoutService 中,我有这个简单的方法:

  logout(username: string) {
    store.dispatch([new ResetStateAction(), new LogoutAction(username)]);
  }
Run Code Online (Sandbox Code Playgroud)

我需要编写一个单元测试来验证这两个操作是否已调度:

  it('should dispatch ResetState and Logout actions', function () {
    logoutService.logout();

    // how to check the dispactched actions and their parameters?
    // expect(...)
  });
Run Code Online (Sandbox Code Playgroud)

我如何检查分派的动作?

Bra*_*age 14

NGXS 可管道操作符

NGXS 中的操作由 Observables 处理。NGXS 为您提供可管道操作符,您可以在测试中使用ofActionDispatched. 这是我从NGXS 文档中获取的列表:

  • ofAction 当以下任何生命周期事件发生时触发
  • ofActionDispatched 当一个动作被分派时触发
  • ofActionSuccessful 当一个动作成功完成时触发
  • ofActionCanceled 当一个动作被取消时触发
  • ofActionErrored 当一个动作导致一个错误被抛出时触发
  • ofActionCompleted 无论是否成功都在操作完成时触发(返回完成摘要)

回答

1. 创建变量 actions$

describe('control-center.state', () => {
  let actions$: Observable<any>;

  // ...
});
Run Code Online (Sandbox Code Playgroud)

2.actions$用 observable初始化变量

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [
      NgxsModule.forRoot([AppState]),
      NgxsModule.forFeature([ControlCenterState])
    ]
  });
  store = TestBed.get(Store);
  actions$ = TestBed.get(Actions);
})
Run Code Online (Sandbox Code Playgroud)

3.1 测试是否调用了 1 个动作:

使用运算符从流中过滤您的操作ofActionsDispatched()

it('should dispatch LogoutAction', (done) => {
  actions$.pipe(ofActionDispatched(LogoutAction)).subscribe((_) => {
    done();
  });

  service.logout();
});
Run Code Online (Sandbox Code Playgroud)

3.2 测试是否调用了多个动作:

使用 RXJS zip 运算符将两个 observable 与ofActionsDispatched()函数组合在一起(zip:在所有observables 发出后,将值作为数组发出)。

it('should dispatch ResetStateAction and LogoutAction', (done) => {
  zip(
    actions$.pipe(ofActionDispatched(ResetStateAction)),
    actions$.pipe(ofActionDispatched(LogoutAction))
  ).subscribe((_) => {
    done();
  });

  service.logout();
});
Run Code Online (Sandbox Code Playgroud)

规范在done被调用之前不会完成。如果done没有被调用,将会抛出一个超时异常。

来自Jasmine 文档