使用Jasmin进行Angular 8单元测试EventSource

时间:2020-05-07 05:29:20

标签: angular typescript jasmine karma-jasmine

我在应用程序中使用了EventSource,并编写了如下所示的包装器服务:

import { Injectable } from '@angular/core';
import { EventSourcePolyfill } from 'event-source-polyfill';
import { Observable } from 'rxjs';
import { AppConstants } from 'src/app/framework/constants/app.constants';

const base_url = `${AppConstants.REST_API_URL}datacontrolmanagment/notification`;

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

  private eventSource;
  constructor() { }


  /**
   * 
   * @param url for Event Source Endpoint
   * @param headers passing authorization token
   */
  private getEventSource(headers) {
    return new EventSourcePolyfill(base_url, headers)
  }

  public getServerSentEvents(headers) {
    return Observable.create(observer => {
      if (!(this.eventSource instanceof EventSourcePolyfill)) {
        this.eventSource = this.getEventSource(headers);
      }

      this.eventSource.onmessage = msg => {
        console.log(msg)
        observer.next(msg);
      };

      this.eventSource.onerror = msg => {

      }; 

    });

  };

  public closeEventSource() {
    if ((this.eventSource instanceof EventSourcePolyfill)) {
      this.eventSource.close();
    }
  }
}

我已经在我的组件之一中使用了这项服务。

为了覆盖代码,我想测试此服务。 但是我无法弄清楚如何测试上面的代码。

我试图创建EventSource的模拟/虚拟类,但是没有运气

注意:我已经测试了该服务的组件代码。

1 个答案:

答案 0 :(得分:0)

由于当前EventSourcePolyfillSseService的内部组成部分,因此您根本不应该嘲笑它。如果它是例如构造函数传递的依赖项,则可以模拟它。

您在这里有2个选项-创建比提供EventSourcePolyfill的工厂令牌,然后可以对其进行模拟。

或者简单地像getServerSentEvents一样掩盖EventSourcePolyfill发出的光。 您可以在问题中分享其代码吗?

对于第一种情况,您可以执行下一步(这是示例,不是工作副本)

const base_url = `${AppConstants.REST_API_URL}datacontrolmanagment/notification`;

export const ESP = new InjectionToken<(headers: any) => EventSourcePolyfill>('ESP', {
    factory: () => headers => new EventSourcePolyfill(base_url, headers),
});
@Injectable({
  providedIn: 'root'
})
export class SseService {

  private eventSource;
  constructor(@Inject(ESP) private eventSourceFactory: (headers: any) => EventSourcePolyfill) {}

  public getServerSentEvents(headers) {
    return Observable.create(observer => {
      if (!(this.eventSource instanceof EventSourcePolyfill)) {
        this.eventSource = this.eventSourceFactory(headers);
      }

      this.eventSource.onmessage = msg => {
        console.log(msg)
        observer.next(msg);
      };

      this.eventSource.onerror = msg => {

      }; 

    });

  };

  public closeEventSource() {
    if ((this.eventSource instanceof EventSourcePolyfill)) {
      this.eventSource.close();
    }
  }
}

现在您可以像这样模拟它

it('', done => {
  const mockESP: any = jasmine.createSpyObj('EventSourcePolyfill', ['onmessage', 'onerror', 'close']);

  const mockFactory: any = jasmine.createSpy('EventSourceFactory');
  mockFactory.and.returnValue(mockESP);

  const service = new SseService(mockFactory);
  service.getServerSentEvents({myHeaders: true}).subscribe(result => {
    expect(result).toBe('test');
    done();
  });
  mockESP.onmessage.calls.argsFor(0)[0]('test');
  expect(mockESP).toHaveBeenCalledWith({myHeaders: true});
}