【发布时间】:2019-02-04 11:20:01
【问题描述】:
Angular 6、Rxjs、Jest、Jasmine-marbles。
非常常见的场景:搜索服务器端项目的组件。 在组件中,有一些控件可以更改搜索条件,我想以“反应式”进行编码。所以在组件代码中我有这样的东西:
class SearchComponent implements OnInit {
public searchData: SearchData = {};
public searchConditions$ = new Subject<SearchData>();
constructor(private searchService: SearchService) { }
public results$: Observable<ResultData> = this.searchConditions$.pipe(
distinctUntilChanged(this.compareProperties), // omissis but it works
flatMap(searchData => this.searchService.search(searchData)),
shareReplay(1)
);
// search actions
ngOnInit() {
this.searchConditions$.next(this.searchData);
}
public onChangeProp1(prop1: string) {
this.searchData = { ...this.searchData, prop1 };
this.searchConditions$.next(this.searchData);
}
public onChangeProp2(prop2: string) {
this.searchData = { ...this.searchData, prop2 };
this.searchConditions$.next(this.searchData);
}
}
即Subject,每次 UI 中的某些内容发生更改时都会触发搜索条件。
现在我想测试一下,搜索服务是否只会针对不同的输入而被调用。 我可以用这种方式“没有弹珠”:
test('when searchConditions$ come with equal events search service will not be called more than once', (done: any) => {
service.search = jest.fn(() => of(TestData.results));
component.results$.subscribe({
complete: () => {
expect(service.Search).toHaveBeenCalledTimes(1);
done();
}
});
component.searchConditions$.next(TestData.searchCriteria);
component.searchConditions$.next(TestData.searchCriteria);
component.searchConditions$.next(TestData.searchCriteria);
component.searchConditions$.complete();
});
现在我想用 jasmine marbles 转换这个测试,但我不知道如何...
我想要这样的东西:
test('when searchConditions$ come with equal events search service will not be called more than once', (done: any) => {
service.search = jest.fn(() => of(TestData.results));
component.searchConditions$ = cold('--a--a|', { a : TestData.searchCriteria});
const expected = cold('--b---|', { b : TestData.results});
expect(component.results$).toBeObservable(expected);
});
显然,它不起作用......
更新
以某种方式接近...使用“测试助手”
test('when searchConditions$ comes with equal events search service will not be called more than once - marble version', () => {
service.search = jest.fn(() => of(TestData.results));
const stream = cold('--a--a|', { a : TestData.searchCriteria});
const expected = cold('--b---|', { b : TestData.results});
stubSubject(component.searchConditions$, stream);
expect(component.results$).toBeObservable(expected);
});
// test helpers
const stubSubject = (subject: Subject<any> , marbles: TestObservable) => {
marbles.subscribe({
next: (value: any) => subject.next(value),
complete: () => subject.complete(),
error: (e) => subject.error(e)
});
};
【问题讨论】:
-
仅供参考,你应该可以写
stream.subscribe(component.searchConditions$)。你写了“somewhere close”,你的方法有什么地方没有奏效吗? -
没什么,它工作正常,只是和我最初想象的有点不同
标签: angular rxjs jestjs jasmine-marbles