Angular 带karma的角度单元测试:会话存储“无法读取未定义的属性”

Angular 带karma的角度单元测试:会话存储“无法读取未定义的属性”,angular,unit-testing,karma-jasmine,Angular,Unit Testing,Karma Jasmine,我有一个服务,在用户登录时将基本用户配置信息存储在会话存储中。然后,我在整个应用程序中调用该服务,在需要时返回配置 export class ClientConfigService { response: LoginConfig = initialClientConfig; private configResponse = new BehaviorSubject(this.response); configData = this.configResponse.asObservable

我有一个服务,在用户登录时将基本用户配置信息存储在会话存储中。然后,我在整个应用程序中调用该服务,在需要时返回配置

export class ClientConfigService {
  response: LoginConfig = initialClientConfig;
  private configResponse = new BehaviorSubject(this.response);
  configData = this.configResponse.asObservable();

  constructor(private apiService: ApiService) { }

  setSessionStorage(data: LoginConfig) {
    sessionStorage.setItem('client', JSON.stringify(data));
    this.configResponse.next(data);
  }

  getClientConfig(clientId: string) {
    const clientSetup =  { startUrl: `${environment.apiUrl}/${clientId}` };

    return this.apiService.post(`yd-core/npb/start`, clientSetup).subscribe((data: LoginConfig) => {
      this.configResponse.next(data);
    });
  }

  getPageData() {
    const sessionConfig: LoginConfig = JSON.parse(sessionStorage.getItem('config'));

    return sessionConfig.client.config;
  }

  getClientId() {
    const sessionConfig: LoginConfig = JSON.parse(sessionStorage.getItem('config'));

    return sessionConfig.client.clientId;
  }

  getCurrentUser() {
    const sessionConfig: LoginConfig = JSON.parse(sessionStorage.getItem('config'));

    return sessionConfig.user;
  }
}
当我运行ng测试时,我得到了许多TypeError的实例:无法读取null的属性“client”

我知道我需要模拟会话存储。。我在这里尝试,但没有效果

import { TestBed } from '@angular/core/testing';

import { ClientConfigService } from './client-config.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { ApiService } from './api.service';
import { initialClientConfig } from '../models/user';

describe('ClientConfigService', () => {
  let httpClient: HttpClient;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    window.sessionStorage.setItem('client', JSON.stringify({client : {} })); 
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        RouterModule.forRoot([]),
      ],
      providers: [
        ApiService
      ]
    })
  .compileComponents();
    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);
  });

  it('should be created', () => {
    const service: ClientConfigService = TestBed.get(ClientConfigService);
    expect(service).toBeTruthy();
  });
});


我可能遗漏了一些东西,但对我来说,设置sessionStorage的唯一时间是使用“client”键,而每次从sessionStorage中提取时,都使用“config”键。这会不会像你把钥匙弄错那么简单?

我认为这更像是一个依赖注入问题。您希望这一行能够正常工作:

  const service: ClientConfigService = TestBed.get(ClientConfigService);
当ClientConfigService不是测试模块的一部分时。另外,因为您的ClientConfigService依赖于ApiService;您必须确保已满足ApiService的依赖项要求

理想情况下,在单元测试中,一次只能测试一件事情。我建议您在此测试中通过更改以下内容模拟您的ApiService:

providers: [
        ApiService
      ]
为此:

providers: [
        {provide: ApiService, useValue: {"...mock properties here"}}
      ]
我希望这有帮助,
Isaac

问题是我只是把钥匙命名错了。我在做什么

window.sessionStorage.setItem('client', JSON.stringify({client : {} })); 
而不是

window.sessionStorage.setItem('config', JSON.stringify(initialClientConfig))

如果用户未登录,则initialClientConfig是占位符/默认配置。