簡體   English   中英

使用Jest進行無法理解的單元測試效果錯誤

[英]Ununderstandable unit testing effects error using Jest

我正在研究兩個幾乎相同的測試用例,我應該聲稱期望兩個NgRx效果返回一個布爾流。 在第一個測試用例中,一切都按預期工作,盡管對第二個測試用例做了同樣的事情,但我無法按預期工作。 無論我做什么,收到的值總是一個空數組:

expect(received).toEqual(expected) // deep equality
    - Expected
    + Received

    - Array [
    -   Object {
    -     "frame": 10,
    -     "notification": Notification {
    -       "error": undefined,
    -       "hasValue": true,
    -       "kind": "N",
    -       "value": true,
    -     },
    -   },
    - ]
    + Array []

工作測試

logger.effects.spec.ts:

describe('LoggerEffects', () => {
    let actions$: Observable<ApiFailure>;
    let effects: LoggerEffects;
    const serviceMock = <AppLoggerServiceI>{ failure: ({ body, title }) => of(true) };
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [StoreModule.forRoot({})],
            providers: [
                LoggerEffects,
                provideMockActions(() => actions$),
                {
                    provide: 'appLoggerService',
                    useValue: serviceMock
                }
            ]
        });
        effects = TestBed.get(LoggerEffects);
    });
    const failure = new HttpErrorResponse({ error: 'HttpErrorResponse' });
    describe('logApiFailure$', () => {
        it('should return a stream of boolean if the dispatched action is ApiActions.searchFailure', () => {
            const action = ApiActions.searchFailure({ failure });
            actions$ = hot('-a--', { a: action });
            const expected = cold('-b--', { b: true });
            expect(effects.logApiFailure$).toBeObservable(expected);
        });
    });
});

logger.effects.ts:

logApiFailure$ = createEffect(
        () =>
            this.actions$.pipe(
                ofType(ApiActions.searchFailure),
                exhaustMap(({ failure: { body, title } }) =>
                    this.appLoggerService.failure({
                        body,
                        title
                    })
                )
            ),
        { dispatch: false }
    );

測試失敗

router.effects.spec.ts:

describe('RouterEffects', () => {
    let actions$: Observable<boolean>;
    let effects: RouterEffects;

    const routerMock = <Partial<Router>>{ navigate: (commands: any[]) => Promise.resolve(true) };

    let router: Router;
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [StoreModule.forRoot({})],
            providers: [
                RouterEffects,
                provideMockActions(() => actions$),
                {
                    provide: Router,
                    useValue: routerMock
                }
            ]
        });
        effects = TestBed.get(RouterEffects);
    });
    describe('navigateTo$', () => {
        it('should return a stream of boolean if the dispatched action is RouterActions.navigateTo', () => {
            const action = RouterActions.navigateTo();
            actions$ = hot('-a--', { a: action });
            const expected = cold('-b--', { b: true });
            console.log('toto', effects.navigateTo$);
            expect(effects.navigateTo$).toBeObservable(expected);
        });
    });
});

router.effects.ts:

navigateTo$ = createEffect(
    () =>
        this.actions$.pipe(
            ofType(RouterActions.navigateTo),
            exhaustMap(() => this.router.navigate(['my-route', {}]))
        ),
    { dispatch: false }
);

在這一點上,我假設router.effects.spec.ts中的Hot Observable有問題,這會阻止效果分派navigateTo動作。 你有什么想法嗎?

項目的依賴關系

{
    "dependencies": {
        "@angular/animations": "^8.0.0",
        "@angular/cdk": "^8.0.0",
        "@angular/common": "^8.0.0",
        "@angular/compiler": "^8.0.0",
        "@angular/core": "^8.0.0",
        "@angular/forms": "^8.0.0",
        "@angular/material": "^8.0.0",
        "@angular/material-moment-adapter": "^8.0.0",
        "@angular/platform-browser": "^8.0.0",
        "@angular/platform-browser-dynamic": "^8.0.0",
        "@angular/router": "^8.0.0",
        "@ngrx/effects": "^8.0.0",
        "@ngrx/router-store": "^8.0.0",
        "@ngrx/store": "^8.0.0",
        "core-js": "^2.5.4",
        "hammerjs": "^2.0.8",
        "moment": "^2.24.0",
        "rxjs": "^6.5.0",
        "tslib": "^1.9.0",
        "zone.js": "^0.9.1"
    },
    "devDependencies": {
        "jest-preset-angular": "7.0.0",
        "@angular-devkit/build-angular": "^0.800.0",
        "@angular-devkit/build-ng-packagr": "~0.800.0",
        "@angular-devkit/core": "^8.0.2",
        "@angular-devkit/schematics": "^8.0.2",
        "@angular/cli": "8.0.0",
        "@angular/compiler-cli": "^8.0.0",
        "@angular/language-service": "^8.0.0",
        "@ngrx/schematics": "^8.0.0",
        "@ngrx/store-devtools": "^8.0.0",
        "@nrwl/cypress": "8.1.0",
        "@nrwl/jest": "8.1.0",
        "@nrwl/workspace": "8.1.0",
        "@nrwl/schematics": "8.1.0",
        "@types/jest": "24.0.9",
        "@types/node": "^12.0.7",
        "codelyzer": "~5.0.1",
        "cypress": "~3.3.1",
        "dotenv": "6.2.0",
        "jest": "24.1.0",
        "ng-packagr": "^5.1.0",
        "prettier": "1.16.4",
        "ts-jest": "24.0.0",
        "ts-node": "^8.2.0",
        "tsickle": "^0.35.0",
        "tslib": "^1.9.0",
        "tslint": "~5.11.0",
        "typescript": "~3.4.5"
    }
}

我只花了一些時間來追蹤類似的問題(空的預期數組),問題證明與TestScheduler未管理的異步代碼有關。 在我的情況下,我使用from([Promise]) 為了解決這個問題,我模擬了函數返回一個返回一個observable of()的promise。

這個問題幫助了我很多,並清楚地解釋了這個問題: https//github.com/cartant/rxjs-marbles/issues/11

在你的情況下,我認為問題是由this.router.navigate(['my-route', {}]) ,它返回一個promise,而不是一個observable。

嘗試router.navigate返回of(true)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM