我正在尝试编写效果单元测试,但我得到了错误NullInjectorError: No provider for StationsListService!
。
我的stations.effets.ts是:
@Injectable()
export class StationsListEffects {
constructor(private actions$: Actions, private stationsListService: StationsListService) {}
@Effect()
loadStationsList$ = this.actions$.pipe(
ofType(StationsListActionTypes.LoadStationsList),
exhaustMap(() => this.stationsListService.getStations()),
map((stationsList: StationListItem[]) => new StationsLoaded(stationsList)),
catchError((error: Error) => of(new StationsLoadFailed(error)))
);
}
stations.effects.spec.ts是:
describe('StationsListEffects', () => {
let actions: Observable<any>;
let effects: StationsListEffects;
let stationsListService: jasmine.SpyObj<StationsListService>;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
StationsListService,
StationsListEffects,
provideMockActions(() => actions),
{
provide: StationsListService,
useValue: {
getStations: jasmine.createSpy(),
},
},
],
});
effects = TestBed.inject(StationsListEffects);
stationsListService = TestBed.inject(StationsListService);
});
describe('loadStationsList', () => {
it('should return a stream with stations list loaded action', () => {
const stationsList: StationListItem[] = [
{
id: '123',
identifier: 'identifier 123',
name: 'west',
address: {
city: 'sv',
streetAndHouseNumber: 'str. Universitatii 13',
postcode: '720234',
state: 'sv',
},
active: false,
},
];
const action = new LoadStationsList();
const outcome = new StationsLoaded(stationsList);
actions = hot('-a', { a: action });
const response = cold('-a|', { a: stationsList });
stationsListService.getStations.and.returnValue(response);
const expected = cold('--b', { b: outcome });
expect(effects.loadStationsList$).toBeObservable(expected);
});
it('should fail and return an action with the error', () => {
const action = new LoadStationsList();
const error = new Error('some error') as any;
const outcome = new StationsLoadFailed(error);
actions = hot('-a', { a: action });
const response = cold('-#|', {}, error);
stationsListService.getStations.and.returnValue(response);
const expected = cold('--(b|)', { b: outcome });
expect(effects.loadStationsList$).toBeObservable(expected);
});
});
});
在stationsListService = TestBed.inject(StationsListService);
,我有一个错误,上面写着:Type 'StationsListService' is not assignable to type 'SpyObj<StationsListService>'.
站点列表服务是:
@Injectable()
export class StationsListService {
private stationList: StationListItem[] = [];
public get stationsList(): StationListItem[] {
return this.stationList;
}
private baseUrl = '//localhost:8080/api/stations';
constructor(private httpClient: HttpClient) {}
public getStations(): any {
return this.httpClient.get<Array<StationListItem>>(this.baseUrl).pipe(
tap((data) => {
this.stationList = data;
})
);
}
public addStation(station: StationListItem): any {
return of(null).pipe(delay(2000));
}
public updateStation(station: StationListItem): any {
return of(null).pipe(delay(2000));
}
public deleteStation(id: string): any {
return of(null).pipe(delay(2000));
}
}
我尝试像stationsListService = TestBed.inject(StationsListService) as jasmine.SpyObj<StationsListService>;
一样将服务作为SpyObj注入,但仍然不起作用。有人知道怎么解决这个问题吗?提前谢谢!
当您试图将类型(由TestBed.inject
返回(分配给不兼容的spy
类型时,编译错误非常明显。要修复此错误,首先更改服务的类型,然后使用spyOn
监视服务上的方法。让我们像这样更新代码-
describe('StationsListEffects', () => {
let actions: Observable<any>;
let effects: StationsListEffects;
let stationsListService: StationsListService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
StationsListService,
StationsListEffects,
provideMockActions(() => actions)
],
});
effects = TestBed.inject(StationsListEffects);
stationsListService = TestBed.inject(StationsListService);
});
describe('loadStationsList', () => {
it('should return a stream with stations list loaded action', () => {
const stationsList: StationListItem[] = [
{
id: '123',
identifier: 'identifier 123',
name: 'west',
address: {
city: 'sv',
streetAndHouseNumber: 'str. Universitatii 13',
postcode: '720234',
state: 'sv',
},
active: false,
},
];
//SPY the function and return mocked data wrapped in an observable using "of" operator
spyOn(stationsListService, 'getStations').and.returnValue(of(stationsList));
const action = new LoadStationsList();
const outcome = new StationsLoaded(stationsList);
actions = cold('-a', { a: action });
const expected = cold('--b', { b: outcome });
expect(effects.loadStationsList$).toBeObservable(expected);
});
});
});