NgRx效果:单元测试-似乎action $从不产生效果

时间:2019-08-19 19:40:05

标签: angular unit-testing ngrx ngrx-effects

运行单元测试时,我注意到Jasmine记录了一条消息,说我的单元测试没有期望。因此,我注意到单元测试效果不佳。似乎该动作并未触发效果。我要提到的是,UI可以毫无问题地获得各个国家/地区

我正在根据https://next.ngrx.io/guide/effectshttps://next.ngrx.io/guide/effects/testing编写代码。

效果

@Injectable()
export class CountryEffects {
    constructor(private actions$: Actions,
        private countryService: CountryService,
        private store: Store<CountryState>) { }

    loadCountries$ = createEffect(() =>
        this.actions$.pipe(
            ofType(CountryActions.ActionTypes.LOAD_COUNTRIES),
            withLatestFrom(this.store.select(selectCountries)),
            mergeMap(([action, storeCountries]) => {

                if (storeCountries && storeCountries.length > 0) {
                    return of(CountryActions.loadCountriesSuccess({ countries: storeCountries }))
                }

                return this.countryService.getAll().pipe(
                    map((apiCountries: Country[]) => CountryActions.loadCountriesSuccess({ countries: apiCountries })),
                    catchError(err =>
                        of(CountryActions.loadCountriesFailure({ error: 'Fail to load countries', countries: null }))
                    )
                )
            })
        )
    );
}

效果规格:

import { of, Observable } from "rxjs";
import { TestBed } from '@angular/core/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { provideMockStore } from '@ngrx/store/testing';

import { CountryService } from 'src/app/vendors/shared/services/country.service';
import { CountryEffects } from './country.effects';


import { COUNTRIES } from 'src/test/mocks/country.mock';
import { Action } from '@ngrx/store';
import { CountryActions } from '.';

describe('CountryEffects', () => {
    let actions$: Observable<Action>;
    let effects: CountryEffects;
    let service: jasmine.SpyObj<CountryService>;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                CountryEffects,
                provideMockActions(() => actions$),
                provideMockStore({
                    selectors: [
                        {
                            selector: CountryActions.ActionTypes.LOAD_COUNTRIES,
                            value: {
                                countries: []
                            }
                        }
                    ]
                }),
                { 
                    provide: CountryService,
                    useValue: jasmine.createSpyObj('countryService', ['getAll'])
                },
            ]
        });

        effects = TestBed.get<CountryEffects>(CountryEffects);
        service = TestBed.get(CountryService);
    });

    it('loadCountries$ should return CountryAction.loadCountriesSuccess', () => {

        actions$ = of({ type: CountryActions.ActionTypes.LOAD_COUNTRIES });
        service.getAll.and.returnValue(of(COUNTRIES));

        effects.loadCountries$.subscribe(action => {
            // Here is where I expect it to fail since the effect should return
            // type ActionTypes.LOAD_COUNTRIES_SUCCESS
            expect(action.type).toEqual('Please fail');
            expect(action.countries).toEqual(COUNTRIES);
        });
    });
});

2 个答案:

答案 0 :(得分:0)

与其使用of创建actions$,而是尝试创建hot如下所示的可观察对象。

 actions$ = hot('-a--', {
    a: { type: CountryActions.ActionTypes.LOAD_COUNTRIES },
  });

答案 1 :(得分:-1)

我最终要做的就是对provideMockStore进行更改,以使用简单的initialState。它包含“状态”的所有属性,这些属性设置为您需要的任何默认值。

providers: [
    CountryEffects,
    provideMockActions(() => actions$),
    provideMockStore({ initialState }),
    {
        provide: CountryService,
        useValue: jasmine.createSpyObj('countryService', ['getAll'])
        },
]