1

我在下面有一个ngrx/效果类。我想测试它,但是当我运行测试时,它没有打印任何东西但仍然通过。测试应该是当我触发动作 TRIGGER_LOAD_NAVIGATION_ITEMS 时,我应该得到模拟结果集并返回动作类型为 LOAD_NAVIGATIONS_LINKS

效果文件

import { Injectable } from '@angular/core';
import { Effect, Actions } from '@ngrx/effects';
import { NavigationActionType } from 'app/core/store/actions/navigation/navigation.action';
import { NavigationService } from 'app/core/services/navigation.service';
import 'rxjs/add/operator/switchMap';

@Injectable()
export class NavigationServiceEffect {
    @Effect()
    navigations$ = this.actions$
                        .ofType(NavigationActionType.TRIGGER_LOAD_NAVIGATION_ITEMS)
                        .switchMap( () => this.navigationService.load())
                        .map(data => ({ type: NavigationActionType.LOAD_NAVIGATIONS_LINKS, payload: data}));

    constructor(private actions$: Actions, private navigationService: NavigationService) {}
}

测试文件

import { Http, Request, RequestOptionsArgs } from "@angular/http";
import { RouterModule, Router } from "@angular/router";


class HttpMock extends Http {

    get(url: string, options?: RequestOptionsArgs): any {

    }

    request(url: string | Request, options?: RequestOptionsArgs): any {

    }
}

fdescribe('Tag Effect', () => {
    let runner: EffectsRunner;
    let navEffects: NavigationServiceEffect;
    let navService: NavigationService;
    let actions: Actions;

    beforeEach(() => TestBed.configureTestingModule({
        imports: [
            EffectsTestingModule,
            RouterModule,
            StoreModule.provideStore(reducers())
        ],
        providers: [
            Actions,
            NavigationService,
            HttpService,
            { provide: Http, useClass: HttpMock },
            { provide: Router, useClass: class { navigate = jasmine.createSpy("navigate"); } }
        ]
    }));

    it('Call Load Navigation items action after Trigger Load aciton',
        inject([
            Actions, NavigationService
        ],
            ( _actions, _navService) => {
                actions = _actions;
                navService = _navService;

                spyOn(navService, 'load')
                    .and.returnValue(Observable.of([
                        { "name": "Help", "hasChild": false, "roles": [101, 151, 201, 301, 401], "url": "help" }
                    ]));


                navEffects = new NavigationServiceEffect(actions, navService);

                navEffects.navigations$.subscribe(r => console.log(r));

                navEffects.navigations$.subscribe(result => {

                    console.log(result);
                    expect(result.type).toEqual(NavigationActionType.LOAD_NAVIGATIONS_LINKS);
                    expect(result.payload.length).toEqual(3); // This should fail

                });
            }));

});

测试应该失败,因为预期有效负载的长度是 1 并且在上面的语句中等于 3,所以它应该失败。但是测试通过了,但没有记录控制台输出。如何测试上述文件?

4

1 回答 1

1

您的断言是在内部定义的subscribe,这使得您的测试是异步的。
事实上,您的测试可能在触发操作结果之前完成。
要解决此问题,您需要使用async如下函数包装您的测试:

   it('Call Load Navigation items action after Trigger Load aciton', 
      async(
        inject([
            Actions, NavigationService
        ],
            ( _actions, _navService) => {
                actions = _actions;
                navService = _navService;

                spyOn(navService, 'load')
                    .and.returnValue(Observable.of([
                        { "name": "Help", "hasChild": false, "roles": [101, 151, 201, 301, 401], "url": "help" }
                    ]));


                navEffects = new NavigationServiceEffect(actions, navService);

                navEffects.navigations$.subscribe(r => console.log(r));

                navEffects.navigations$.subscribe(result => {

                    console.log(result);
                    expect(result.type).toEqual(NavigationActionType.LOAD_NAVIGATIONS_LINKS);
                    expect(result.payload.length).toEqual(3); // This should fail

                });
            })));  

更多关于async 这里

于 2017-06-27T12:37:24.170 回答