如何模拟更复杂的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));
我知道这两个示例都是伪代码,但我希望它们能证明我正在尝试实现的目标。如果我的方法完全错误,请对此发表评论。
答案 0 :(得分:1)
使用RxJs Marbles通过NgRx测试RxJ。
有关更多信息,请阅读RxJS Marble Testing: RTFM并查看Jest Testing - Jesse Sanders,Reactive 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');
});
});