开玩笑:模拟RxJs管道

时间:2018-09-27 08:25:10

标签: angular typescript rxjs jestjs ngrx

如何模拟更复杂的RxJs行为(在NgRx的情况下)?

给出一个简单的组件(SomeComponent):

export class SomeComponent implements OnInit {
  foo$: Observable<any>;
  bar$: Observable<any>;

  constructor(private store: Store<State>) {}

  ngOnInit() {
    this.foo$ = this.store.pipe(select(getFooSelector));
    this.bar$ = this.store.pipe(select(getBarSelector));
  }
}

我想通过以下方式来模拟存储:

  • 基于传递的选择器,模拟存储返回不同的值。
  • 监视将什么参数(选择器)传递给select运算符。

基于传递的选择器,模拟存储返回不同的值

我会这样看:

store.pipe = jest.fn(selectOperator => {
  switch (selectOperator.arguments[0]) {
    case getFooSelector:
      return foo;
    case getBarSelector:
      return bar;
  }
}

监视将什么参数(选择器)传递给select运算符。

遵循这些原则:

const spy = jest.spyOn(store, 'pipe');
expect(spy.mock.calls[0]).toHaveBeenCalledWith(select(getFooSelector));
expect(spy.mock.calls[1]).toHaveBeenCalledWith(select(getBarSelector));

摘要

我知道这两个示例都是伪代码,但我希望它们能证明我正在尝试实现的目标。如果我的方法完全错误,请对此发表评论。

2 个答案:

答案 0 :(得分:1)

使用RxJs Marbles通过NgRx测试RxJ。

有关更多信息,请阅读RxJS Marble Testing: RTFM并查看Jest Testing - Jesse SandersReactive Testing Strategies with NgRx - Brandon Roberts & Mike Ryan

要实施,请使用jest.fn().mockImplementationOnce

store.pipe = jest.fn()
   .mockImplementationOnce(foo)
   .mockImplementationOnce(bar)

expect(store.pipe).toHaveBeenCalledWith(select(getFooSelector));
expect(store.pipe).toHaveBeenCalledWith(select(getBarSelector));

答案 1 :(得分:1)

使用NGRX v8.6.0,您应该可以执行以下操作:

let fixture: ComponentFixture<SomeComponent>;
let mockStore: MockStore<State>;

beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [provideMockStore()],
        declarations: [SomeComponent],
    });

    fixture = TestBed.createComponent(SomeComponent);
    mockStore = TestBed.get(Store);
    fixture.detectChanges();
});

it('should have a value of foo', done => {
    mockStore.overrideSelector(getFooSelector, 'foo');

    foo$.subscribe(res => {
        done();
        expect(res).toBe('foo');
    });
});

it('should have a value of bar', done => {
    mockStore.overrideSelector(getBarSelector, 'bar');

    bar$.subscribe(res => {
        done();
        expect(res).toBe('bar');
    });
});

https://ngrx.io/guide/store/testing