angular - 如何测试 Action 是否在 NgRX 中发送?

标签 angular karma-jasmine ngrx ngrx-store

我有一个在构造函数中分派(dispatch) Action 的组件:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {    
  constructor(store: Store<State>) {
    store.dispatch(action1());
    store.dispatch(action2());
  }
}
我需要测试 action1 和 action2 是否被调度。我正在尝试使用 MockStore 来做到这一点:
import {MockStore, provideMockStore} from '@ngrx/store/testing';

let store: MockStore;

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [
      AppComponent
    ],
    providers: [
      provideMockStore({ initialState }),
    ],
  }).compileComponents();
  store = TestBed.inject(MockStore);
});
这是我的测试:
it('should dispatch an action1 in constructor', () => {
  TestBed.createComponent(AppComponent);

  const expected = cold('a', {a: action1()});

  expect(store.scannedActions$).toBeObservable(expected);
});

it('should dispatch an action2 in constructor', () => {
  TestBed.createComponent(AppComponent);

  const expected = cold('a', {a: action2()});

  expect(store.scannedActions$).toBeObservable(expected);
});
这很奇怪,但只通过了一项测试。这取决于 dispatch() 调用的顺序。
store.scannedActions$ 只包含一个值。如果组件代码是:
constructor(store: Store<State>) {
  store.dispatch(action1());
  store.dispatch(action2());
}
那么 store.scannedActions$ 只包含 action2()如果组件代码是:
constructor(store: Store<State>) {
  store.dispatch(action2());
  store.dispatch(action1());
}
那么 store.scannedActions$ 只包含 action1()如何测试这两个 Action ?

最佳答案

好像scannedActions$即使它是复数 (actions) 也只存储了最后一个调度的 Action,查看它的 interface .
我只会用 spyOn并监视 store.dispatch看看它是否是用正确的 Action 调用的。

import {MockStore, provideMockStore} from '@ngrx/store/testing';

let store: MockStore;

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [
      AppComponent
    ],
    providers: [
      provideMockStore({ initialState }),
    ],
  }).compileComponents();
  store = TestBed.inject(MockStore);
});

it('should dispatch action1 and action 2 in constructor', () => {
  const dispatchSpy = spyOn(store, 'dispatch').and.callThrough(); // spy on the store 
  // dispatch but still call the actual implementation
  TestBed.createComponent(AppComponent);
  fixture.detectChanges(); // used to call ngOnInit, maybe it is not needed

  expect(dispatchSpy).toHaveBeenCalledWith(action1());
  expect(dispatchSpy).toHaveBeenCalledWith(action2());
});

关于angular - 如何测试 Action 是否在 NgRX 中发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65108648/

相关文章:

javascript - 处理 NGRX 效果后的操作

angular - 将 http 与 ngBootstrap Typeahead 一起用于 Angular 4

angular - 如何在 Angular 2 的 ES5 风格的自定义指令中使用 ng.core.HostListener 和 ng.core.HostBinding

javascript - Angular2 + karma 测试 : “Illegal state: Could not load the summary for directive Foo.”

angular - 无法在 Angular Testing 用例中使用 TestBed.overrideProvider 覆盖 MAT_DIALOG_DATA 提供程序

typescript - 具有枚举类型问题的 Ngrx 操作

Angular ngrx : guards with side-effect

asp.net-mvc - 使用 MVC5 应用程序的 Angular Cli 延迟加载

javascript - 使用嵌套数组对象迭代数组的属性

angular - 使用 Jasmine 测试 ngSwitch