【发布时间】:2022-01-22 02:13:58
【问题描述】:
我正在尝试在 Angular 中测试来自服务的 observable,这取决于 queryParam 的值。
在尝试模拟 queryParam 以便能够对 observable 执行测试时,我非常卡住。
我尝试了不同的方法,但无法实现 queryParam 值。
这是服务:
import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class CarService {
private readonly _car$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(this.carStatus);
constructor(private route: ActivatedRoute) {}
public get car$(): Observable<boolean> {
return this._car$.asObservable();
}
private get carStatus(): boolean {
const isHybrid = this.route.snapshot.queryParamMap.get('hybrid') === 'true';
if (isHybrid) return true;
return false;
}
}
这些是测试文件的不同方法:
选项 1
import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { CarService } from './carService.service';
describe('CarService', () => {
let service: CarService;
let route: ActivatedRouteSnapshot;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [CarService],
});
route = new ActivatedRouteSnapshot();
});
describe('When there is a hybrid car', () => {
it('should enable the electric mode', (done) => {
route.queryParams = {
hybrid: 'true',
};
service = TestBed.inject(CarService);
service.car$.subscribe((value: boolean) => {
expect(value).toBe(true);
done();
});
});
});
describe('When the car is not hybrid', () => {
it('should NOT enable the electric mode', (done) => {
route.queryParams = {
hybrid: 'false',
};
service = TestBed.inject(CarService);
service.car$.subscribe((value: boolean) => {
expect(value).toBe(false);
done();
});
});
});
选项 2
import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { CarService } from './carService.service';
describe('CarService', () => {
let service: CarService;
let route: ActivatedRouteSnapshot;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [
CarService,
{
provide: ActivatedRouteSnapshot,
useValue: {
snapshot: {
queryParams: {
hybrid: ‘true’,
},
},
},
},
],
});
route = TestBed.inject(ActivatedRouteSnapshot);
service = TestBed.inject(CarService);
});
describe('When there is a hybrid car', () => {
it('should enable the electric mode', (done) => {
service.car$.subscribe((value: boolean) => {
expect(value).toBe(true);
done();
});
});
});
使用 spyOn 的选项 3
describe('When there is a hybrid car', () => {
it('should enable the electric mode', (done) => {
const route = new ActivatedRouteSnapshot();
spyOn(route.queryParamMap, 'get').and.returnValue('true');
service = TestBed.inject(CarService);
service.car$.subscribe((value: boolean) => {
expect(value).toBe(true);
done();
});
});
});
我还尝试在此处的文档 (https://angular.io/guide/testing-components-scenarios#routed-components) 中实现 ActivatedRouteStub,但我的观点与前面的选项相同。服务中的 get carStatus() 永远无法读取 queryParam,因为它是空的。
如果有人能帮我解决这个问题,我将不胜感激。
【问题讨论】:
标签: javascript angular typescript unit-testing testing