如何在从 ngx-webstorage-service 实现 SessionStorage 的 Angular 测试中模拟服务?

How to mock service in Angular tests which implements SessionStorage from ngx-webstorage-service?

我在 Angular6 中测试我的服务时遇到问题。该服务实现了我从 'ngx-webstorage-service' 库中获得的 SessionStorage。当用户单击另一个选项卡时,我正在使用它来保留选择的产品。不幸的是它不起作用。第一个测试不起作用(应该创建服务)。我应该如何模拟服务并添加InjectionToken?

我试图将模拟会话对象声明为 StorageService,但 Angular 给我一个错误。这是我第一次在测试中使用这个库。

我的构造函数服务如下所示:

import { Injectable, Inject, InjectionToken } from '@angular/core';
import { StorageService } from 'ngx-webstorage-service';

const STORAGE_KEY = 'productId';

export const MY_PRODUCTS_SERVICE_STORAGE =
  new InjectionToken<StorageService>('MY_PRODUCTS_SERVICE_STORAGE');

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  productIds: number[] = [];

  constructor(@Inject(MY_PRODUCT_SERVICE_STORAGE) private storage: StorageService) {
    const ids: number[] = this.storage.get(STORAGE_KEY);
    if (typeof ids !== 'undefined') {
      this.productIds= ids;
    }
  }  
}

我的测试规范文件:

import { TestBed, inject } from '@angular/core/testing';
import { ProductService, MY_PRODUCT_SERVICE_STORAGE } from './product.service';
import { StorageService, SESSION_STORAGE } from 'ngx-webstorage-service';

describe('ProductService ', () => {
  let service: ProductService;
  const mockSession =  {
    get: () => '',
    set: () => null,
    has: () => true,
    remove: () => null,
    clear: () => null,
    withDefaultTranscoder: () => null
  } as StorageService;

  beforeEach(() =>
    service = TestBed.get(ProductService));

  TestBed.configureTestingModule({
    providers: [
      ProductService,
      { provide: MY_PRODUCTS_SERVICE_STORAGE, useExisting: SESSION_STORAGE }
    ]
  });

  it('should be created', inject([mockSession], () => {
    expect(service).toBeTruthy();
  }));
});

预期输出是创建服务,但不幸的是我从 angular 测试中得到错误: 错误:StaticInjectorError(DynamicTestModule)[InjectionToken MY_PRODUCTS_SERVICE_STORAGE]: StaticInjectorError(平台:核心)[InjectionToken MY_PRODUCTS_SERVICE_STORAGE]: NullInjectorError:没有 InjectionToken 的提供者 MY_PRODUCTS_SERVICE_STORAGE!

我已经替换了:

get: ()  => ''

至:

get: () => []

和:

useExisting: SESSION_STORAGE

至:

useValue: mockSession

和:

it('should be created', inject([mockSession], () => {
    expect(service).toBeTruthy();
  }));

至:

it('should be created', () => {
    expect(service).toBeTruthy();
  });

终于成功了。