【问题标题】:Unit testing - getting TypeError: You provided an invalid object where a stream was expected单元测试 - 获取 TypeError:您在预期流的位置提供了无效对象
【发布时间】:2019-05-23 22:52:00
【问题描述】:

我正在尝试进行单元测试,其中效果使用服务从 API 获取结果,然后触发成功操作或错误操作。我不断收到错误TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.。不完全确定需要进行哪些更改才能使其正常工作。

包括错误检查测试和相关代码。

角度

Angular CLI: 7.1.4
Node: 10.5.0
OS: win32 x64
Angular: 7.1.4
... animations, cli, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.10.7
@angular-devkit/build-angular     0.10.7
@angular-devkit/build-optimizer   0.10.7
@angular-devkit/build-webpack     0.10.7
@angular-devkit/core              7.0.7
@angular-devkit/schematics        7.1.4
@angular/cdk                      7.2.0
@angular/material                 7.2.0
@ngtools/webpack                  7.0.7
@schematics/angular               7.1.4
@schematics/update                0.11.4
rxjs                              6.3.3
typescript                        3.1.6
webpack                           4.19.1

测试

describe('ResultsEffects', () => {
    let store: jasmine.SpyObj<Store<FeatureState>>;
    let ebs: jasmine.SpyObj<EBSService>;
    let snackbar: jasmine.SpyObj<SnackBarService>;

    beforeEach(() => {
        store = jasmine.createSpyObj('store', ['pipe']);
        ebs = jasmine.createSpyObj('EBSService', ['getPollResults', 'getUserHasVoted', 'getSettings']);
        snackbar = jasmine.createSpyObj('SnackBarService', ['notify']);
    });

    describe('fetchResults', () => {
        it(`should dispatch 'FetchPanelResultsError'`, () => {
            const fetchAction = new FetchPanelResults();
            const error = { statusText: 'ERROR' };
            const errorAction = new FetchPanelResultsError({ error: error.statusText });
            const values = {
                a: fetchAction,
                e: errorAction
            };
            const source = cold('a', values);
            const expected = cold('--e', values);
            const actions = new Actions(source);

            ebs.getPollResults.and.returnValue(throwError(error));

            const effects = new ResultsEffects(
                actions,
                store,
                snackbar,
                ebs
            );

            expect(
                effects.fetchResults$({
                    debounce: 20,
                    scheduler: getTestScheduler()
                })
            ).toBeObservable(expected);
        });
    });
});

效果

@Effect()
fetchResults$ = ({ debounce = 500, scheduler = asyncScheduler } = {}) => this.actions$.pipe(
    ofType<SetPanelResults>(PanelResultsActionTypes.FETCH_PANEL_RESULTS),
    // need alternate method for this
    // withLatestFrom(this.featureState$),
    // map(([_, state]) => state.twitch.token),
    debounceTime(debounce, scheduler),
    switchMap((token) =>
        this.ebs.getPollResults(token).pipe(
            map(res => new SetPanelResults(res.data.results)),
            catchError(error => of(new FetchPanelResultsError({ error: error.statusText })))
        )
    )
)

服务

getPollResults(token: string): Observable<PollResultsFetchData> {
    const options = {
        headers: ebsHeaders(token)
    };

    return this.http.get<PollResultsFetchData>(`${this.ebsURL}/poll/results`, options);
}

更新:添加了 debounce 以触发弹珠错误。仍然需要替代withLatestFrom

【问题讨论】:

  • 在测试中用 of() 包裹 expectedexpect(effects.fetchResults$()).toBeObservable(of(expected));

标签: angular jasmine ngrx jasmine-marbles


【解决方案1】:

基于 cmets:

问题是 withLatest from 并没有真正返回任何东西,因为您没有功能状态。这是因为您使用jasmine.createSpyObj('store', ['pipe']) 模拟了商店。

要解决这个问题,请使用“真正的”ngrx 存储或使用在 NgRx 7 中实现的mock store

【讨论】:

  • 当我尝试我得到同样的错误。我遵循here 使用的模式。我已经克隆了那个 repo,并运行了测试,它们都通过了。
  • 我认为我们走在正确的轨道上。我添加了一个去抖动,因为我的错误没有触发,然后删除 withLatestFrom 修复了错误。现在我只需要找出另一种方法,在不丢失操作和不破坏 Observable 的情况下让某些东西脱离状态。
  • 是的,将其更改为模拟商店而不是间谍现在已经解决了这个问题。非常感谢您的帮助!
【解决方案2】:

对我来说,在开发过程中 Live Reload 的几个月(Angular 7)开始经常发生错误。我只是通过暂停几秒钟重新打开浏览器来修复它。

今天重新打开并没有帮助,我偶尔发现,重新保存一个源文件(即使没有实际更改它)会有所帮助并且错误会消失。重新保存通过 webpack 和实时重新加载触发项目内存构建重新编译

【讨论】:

    猜你喜欢
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2020-06-16
    • 2021-12-10
    • 2020-02-09
    • 2018-09-07
    相关资源
    最近更新 更多