[英]Angular CLI Unit Testing An Extended Window Method
I am trying to write a unit test for an Angular CLI (v6.0.8, with @angular/core
v6.0.9) component that calls a method on the window object injected via a service, but I'm running into some issues.我正在尝试为 Angular CLI(v6.0.8,带有@angular/core
v6.0.9)组件编写单元测试,该组件调用通过服务注入的 window 对象上的方法,但我遇到了一些问题。
Here is the component: MyComponent
这是组件: MyComponent
import { WindowRefService} from '../../services/window-reference/window-reference.service'
export class MyComponent {
constructor(private windowRef: WindowRefService) {}
addAnother() {
if ((this.windowRef.nativeWindow._thirdPartyWindowObject) {
this.windowRef.nativeWindow._thirdPartyWindowObject.track("toolstart")
}
}
}
and here is the service: WindowRefService
这是服务: WindowRefService
import { Injectable } from '@angular/core'
export interface ICustomWindow extends Window {
_thirdPartyWindowObject: {
track: Function
}
}
function getWindow (): any {
return window
}
@Injectable()
export class WindowRefService {
get nativeWindow (): ICustomWindow {
return getWindow()
}
}
This service is a way to extend the Window
type to include a third party library introduced into the window object in the page the app is loaded into.此服务是一种扩展Window
类型以包含引入到应用程序加载到的页面中的 window 对象中的第三方库的方法。 Not ideal, I know, but it's the use case I was handed.不理想,我知道,但这是我得到的用例。
This is the test I've written for the addAnother
method:这是我为addAnother
方法编写的测试:
import { async, ComponentFixture, TestBed } from '@angular/core/testing'
import { MyComponent } from './MyComponent'
import { WindowRefService, ICustomWindow } from '../../services/window-reference/window-reference.service'
class WindowServiceMock {
get nativeWindow (): ICustomWindow {
return {
...window,
_thirdPartyWindowObject: {
track: (props: string) => {
console.log('props', props)
return true
}
}
}
}
}
describe('MyComponent', () => {
let component: MyComponent
let fixture: ComponentFixture<MyComponent>
let windowSpy: WindowServiceMock
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MyComponent ],
})
.overrideComponent(MyComponent, {
set: {
providers: [
{ provide: WindowRefService, useClass: WindowServiceMock }
]
}
})
.compileComponents()
}))
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent)
component = fixture.componentInstance
windowSpy = fixture.debugElement.injector.get(WindowRefService) as any
fixture.detectChanges()
})
it('should call the third party scripts', () => {
let spy = spyOn(windowSpy.nativeWindow._thirdPartyWindowObject, 'track')
component.addAnother()
expect(spy).toHaveBeenCalled()
})
})
This all works perfectly up until the point I would expect the spy
for windowSpy.nativeWindow._thirdPartyWindowObject.track
to have been called.这一切都很完美,直到我期望windowSpy.nativeWindow._thirdPartyWindowObject.track
的spy
被调用windowSpy.nativeWindow._thirdPartyWindowObject.track
。 When I check my logs, I can see the toolstart
string being passed into the track
method inside WindowServiceMock
being logged out so the stubbed service is being called.当我检查我的日志,我可以看到toolstart
字符串被传递到track
内的方法WindowServiceMock
被记录了这样的存根服务被调用。 However, for some reason, the spy is not.然而,出于某种原因,间谍不是。
I'm sure I'm missing something extremely obvious here, but any help would be appreciated.我确定我在这里遗漏了一些非常明显的东西,但任何帮助将不胜感激。
Thanks!谢谢!
The issue is that the nativeWindow getter is returning a new object every time it is accessed.问题是nativeWindow getter 每次访问时都会返回一个新对象。 So the function you spied on is not the same one that then gets called later.因此,您监视的函数与稍后调用的函数不同。 Updating the mock's getter to always return a reference to the same _thirdPartyWindowObject object, and hence the same child function, as shown below should fix the issue.更新模拟的 getter 以始终返回对相同_thirdPartyWindowObject对象的引用,因此相同的子函数,如下所示应该可以解决问题。 Not sure if there is a better the jasmine way to do this though.不确定是否有更好的茉莉花方式来做到这一点。
const _thirdPartyWindowObject = {
track: (props: string) => {
console.log('props', props)
return true
}
}
class WindowServiceMock {
get nativeWindow (): ICustomWindow {
return {
...window,
_thirdPartyWindowObject
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.