【问题标题】:Angular CLI Unit Testing An Extended Window MethodAngular CLI 单元测试扩展窗口方法
【发布时间】:2019-01-30 08:05:32
【问题描述】:

我正在尝试为 Angular CLI(v6.0.8,带有@angular/core v6.0.9)组件编写单元测试,该组件调用通过服务注入的窗口对象上的方法,但我遇到了一些问题.

这是组件: 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")
    }
  }
}

这里是服务: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()
    }
}

此服务是一种扩展Window 类型的方法,以包含引入到应用程序加载到的页面中的窗口对象中的第三方库。不理想,我知道,但这是我收到的用例。

这是我为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()
  })
})

这一切都完美无缺,直到我预计 windowSpy.nativeWindow._thirdPartyWindowObject.trackspy 已被调用。当我检查我的日志时,我可以看到 toolstart 字符串被传递到 WindowServiceMock 内的 track 方法被注销,因此存根服务 is 被调用。但是,由于某种原因,间谍不是。

我确定我在这里遗漏了一些非常明显的东西,但我们将不胜感激。

谢谢!

【问题讨论】:

  • 您是否看到任何错误?如果是这样,您看到了什么错误?
  • @AlexFallenstedt 测试错误为:Expected spy track to have been called.

标签: angular unit-testing jasmine angular-cli


【解决方案1】:

问题在于 nativeWindow getter 每次访问时都会返回一个新对象。因此,您监视的函数与稍后调用的函数不同。更新 mock 的 getter 以始终返回对相同 _th​​irdPartyWindowObject 对象的引用,因此相同的子函数应该可以解决问题,如下所示。不确定是否有更好的茉莉花方式来做到这一点。

const _thirdPartyWindowObject = {
  track: (props: string) => {
    console.log('props', props)
    return true
  }
}

class WindowServiceMock {
  get nativeWindow (): ICustomWindow {
    return {
      ...window,
      _thirdPartyWindowObject
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2017-04-29
    • 2018-05-10
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多