NgRx testing - NullInjectorError: No provider for Service
NgRx testing - NullInjectorError: No provider for Service
我正在尝试为效果编写单元测试,但遇到错误 NullInjectorError: No provider for StationsListService!
。
我的stations.effects.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>'.
站-list.service.ts是:
@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 注入,但仍然无效。
有人有 ide 如何解决这个问题吗?
提前致谢!
编译错误非常明显,因为您试图将类型(return by 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);
});
});
});
我正在尝试为效果编写单元测试,但遇到错误 NullInjectorError: No provider for StationsListService!
。
我的stations.effects.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>'.
站-list.service.ts是:
@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 注入,但仍然无效。
有人有 ide 如何解决这个问题吗?
提前致谢!
编译错误非常明显,因为您试图将类型(return by 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);
});
});
});