【问题标题】:How to mock a queryParam for a service testing in Angular?如何在 Angular 中模拟 queryParam 以进行服务测试?
【发布时间】: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


    【解决方案1】:

    试试这个(我们正在使用选项 1):

    import { TestBed } from '@angular/core/testing';
    
    import { CarService } from './carService.service';
    
    
    describe('CarService', () => {
      let service: CarService;
      let route: ActivatedRoute;
      let queryParamMapGet: jasmine.Spy;
    
      beforeEach(() => {
        // create a spy for the get method
        queryParamMapGet = jasmine.createSpy('queryParamMapGet');
        TestBed.configureTestingModule({
          providers: [CarService
            { 
              provide: ActivatedRoute, 
              useValue: { 
               snapshot: {
                  queryParamMap: {
                            get: queryParamMapGet // assign it to the get spy
                  } 
              } 
             } 
            }
          ],
        });
      });
    
      describe('When there is a hybrid car', () => {
        it('should enable the electric mode', (done) => {
          // return true for the get value
          queryParamMapGet.and.returnValue('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) => {
          // return false for the get value
          queryParamMapGet.and.returnValue('true');
    
          service = TestBed.inject(CarService);
    
          service.car$.subscribe((value: boolean) => {
            expect(value).toBe(false);
            done();
          });
        });
      });
    

    【讨论】:

      猜你喜欢
      • 2020-02-08
      • 2011-03-12
      • 1970-01-01
      • 2021-09-18
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 2017-06-25
      相关资源
      最近更新 更多