角度测试:订阅组件构造函数中的服务未定义

时间:2019-04-06 18:15:33

标签: angular typescript

在组件的构造函数中订阅了一项服务。在编写测试用例时,它为此this.data提供了未定义的条件。

我尝试使用间谍和模拟游戏

CrossValidated.com

Service.ts

  export class MyComponent {
  private data;
  constructor(private myservice:MyService) {
      this.myService.currentMessage.subscribe((message) => this.data = message);
   if(this.data) {
     let response = true;
  } else {
     let response = false;
}

测试用例

  @Injectable()
  export class MyService {

    private messageSource = new BehaviorSubject<string>("");
    public currentMessage = this.messageSource.asObservable();
    constructor() { }
     changeMessage(message: string) {
     this.messageSource.next(message);
  }
 }

2 个答案:

答案 0 :(得分:0)

除非我缺少一些东西,否则问题是因为您的构造函数在更改服务的可观察值之前已经完成。

 fixture = TestBed.createComponent(MyComponent); // The MyComponent constructor runs here
 component = fixture.componentInstance;
 let service = fixture.debugElement.injector.get(MyService);
 service.currentMessage = Observable.of(data); // The Observable is changed here.

要解决此问题,我认为,您需要在提供的模拟服务中更改从currentMessage读取的data

const dataServiceStub = { currentMessage: Observable.of(data) };

答案 1 :(得分:0)

在构造对象之后,您似乎spy正在 之后。这意味着您的observable在创建spy之前已经被触发。

在构造组件之前尝试spy

let service;
  beforeEach(() => {
         spyOn(service, 'currentMessage').and.returnValue(whatever you want to return);

         fixture = TestBed.createComponent(MyComponent);
         component = fixture.componentInstance;

         service = fixture.debugElement.injector.get(MyService);
         service.currentMessage = Observable.of(data);
   });

此外,您的.ts文件中的模式看起来有些偏离。

this.data将始终是未定义的,因为您的if语句紧接在上一行之后,而不是则在可观察到的返回值之后。要解决此问题,您需要执行以下操作。

  export class MyComponent {
  private data;
  constructor(private myservice:MyService) {
      this.myService.currentMessage.subscribe((message) => {
        this.data = message
        if(this.data) {
          let response = true;
        } else {
          let response = false;
        }
     });

只需检查if (message)并完全避开该字段即可简化此操作。 希望这会有所帮助!