![](/img/trans.png)
[英]Angular 2+ Unit testing a service that calls a service that calls an httpclient get
[英]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.