簡體   English   中英

Angular CLI 單元測試擴展窗口方法

[英]Angular CLI Unit Testing An Extended Window Method

我正在嘗試為 Angular CLI(v6.0.8,帶有@angular/core v6.0.9)組件編寫單元測試,該組件調用通過服務注入的 window 對象上的方法,但我遇到了一些問題。

這是組件: 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類型以包含引入到應用程序加載到的頁面中的 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被調用windowSpy.nativeWindow._thirdPartyWindowObject.track 當我檢查我的日志,我可以看到toolstart字符串被傳遞到track內的方法WindowServiceMock被記錄了這樣的存根服務調用。 然而,出於某種原因,間諜不是。

我確定我在這里遺漏了一些非常明顯的東西,但任何幫助將不勝感激。

謝謝!

問題是nativeWindow getter 每次訪問時都會返回一個新對象。 因此,您監視的函數與稍后調用的函數不同。 更新模擬的 getter 以始終返回對相同_thirdPartyWindowObject對象的引用,因此相同的子函數,如下所示應該可以解決問題。 不確定是否有更好的茉莉花方式來做到這一點。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM