繁体   English   中英

Angular 2+ Promise 单元测试

[英]Angular 2+ Promise Unit testing

嗨,我正在尝试为以下角度服务编写 jasmine 单元测试。

但是,我正在努力如何编写返回承诺值的测试,并且无法找到任何详细的资源如何为这些情况编写。

大多数困难来自不知道如何测试返回的承诺中调用的内容。

例如,我想测试调用this.createMap()调用this._mapResolver与地图实例new google.maps.Map(el, mapOptions)

Angular 2+ 大师可以帮助我理解 Promise 的编写规范吗? 或参考学习?

declare let google: any;

/**
 * Wrapper class that handles the communication with the Google Maps Javascript
 * API v3
 */
@Injectable()
export class GoogleMapsAPIWrapper {
  private _map: Promise<mapTypes.GoogleMap>;
  private _mapResolver: (value?: mapTypes.GoogleMap) => void;

  constructor(private _loader: MapsAPILoader, private _zone: NgZone) {
    this._map =
      new Promise<mapTypes.GoogleMap>((resolve: () => void) => { this._mapResolver = resolve; });
  }

  createMap(el: HTMLElement, mapOptions: mapTypes.MapOptions): Promise<void> {
    return this._loader.load().then(() => {
      const map = new google.maps.Map(el, mapOptions);
      this._mapResolver(<mapTypes.GoogleMap>map);
      return;
    });
  }

  setMapOptions(options: mapTypes.MapOptions) {
    this._map.then((m: mapTypes.GoogleMap) => { m.setOptions(options); });
  }
}

@ArmenVardanyan 建议的解决方案

describe('Service: GoogleMapsAPIWrapper', () => {

  const loaderServiceStub = {
    load: () => Promise.resolve()
  };

  let service;


  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [
        GoogleMapsAPIWrapper,
        {provide: MapsAPILoader, useValue: loaderServiceStub}
      ]
    });
  }));

  beforeEach(async(inject([GoogleMapsAPIWrapper], (_service: GoogleMapsAPIWrapper) => {
    service = _service;
  })));


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

  it('should be call _mapResolver with specified arguments', async(() => {
    const elem = document.createElement('div');
    const spyOnCreateMap = spyOn(service, '_mapResolver');
    service.createMap(elem, {})
      .then(() => {
        expect(spyOnCreateMap).toHaveBeenCalled();
        expect(spyOnCreateMap).toHaveBeenCalledWith(new google.maps.Map(elem, {}));
      });
  }));

});

我不记得如何正确注入 NgZone int 测试,但据我所知,这与您的问题无关。 所以你只需要模拟 MapsAPILoader 服务并测试_mapResolver

 const loaderServiceStub = { load: () => Promise.resolve() }; describe('GoogleMapsAPIWrapper', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [ GoogleMapsAPIWrapper, {provide: MapsAPILoader, useValue: loaderServiceStub} ] }); }); it('should be created', inject([GoogleMapsAPIWrapper], (service: GoogleMapsAPIWrapper) => { expect(service).toBeTruthy(); })); it('should be call _mapResolver with specified arguments', inject([GoogleMapsAPIWrapper], (service: GoogleMapsAPIWrapper) => { const spyOnCreateMap = spyOn(service, '_mapResolver'); service.createMap(new HTMLDivElement(), {/*options */}); expect(spyOnCreateMap).toHaveBeenCalled(); })); });

因此,您基本上模拟加载器服务,以便在调用load时返回一个已解决的 Promise,然后检查_mapResolver是否已被调用。 但是由于以下几行,您无法检查提供的参数是否正确:

const map = new google.maps.Map(el, mapOptions);
this._mapResolver(<mapTypes.GoogleMap>map);

在传递给then方法的回调中创建了一个映射,但您无法知道该对象将是什么。 你可以试试

expect(spyOnCreateMap).toHaveBeenCalledWith(new google.maps.Map(el, mapOptions));

但我几乎可以肯定它不会起作用。 您要编写的第二个测试也存在同样的问题: _map承诺将返回一个具有setOptions方法的对象,但您并不真正知道该对象将是什么。 否则,您将不得不模拟该 Promise,然后确保您模拟的setOptions方法已被调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM