2017-02-02 70 views
3

我正在嘗試編寫一個單元測試,檢查焦點事件的效果是否發生。我的實際測試情況是比較複雜的,但我已經創建了一個最小的再現與下面的代碼:Angular 2 + Jasmine:測試焦點時的瀏覽器焦點

it('testing input focus', async(() => { 
    let showDiv = false; 
    const template = `<div *ngIf="shouldShow" class='hidden-div'> 
         SHOW ME WHAT YOU GOT 
        </div> 
        <input (focus)="shouldShow = !shouldShow" name="input">`; 
    buildTestComponent(template, {shouldShow: showDiv}).then((fixture) => { 
    fixture.detectChanges(); 
    const inputEl: HTMLInputElement = fixture.nativeElement.querySelector('input'); 

    expect(fixture.nativeElement.querySelector('.hidden-div')).toBe(null); 

    inputEl.focus(); 
    fixture.detectChanges(); 

    expect(fixture.nativeElement.querySelector('.hidden-div')).not.toBe(null); 
    }); 
})); 

當我運行該測試業力測試通過了,只要我有焦點的Chrome標籤頁上運行業力目標。但是,如果瀏覽器不具有焦點測試失敗(即使瀏覽器是可見的,但我點擊另一個窗口),並顯示錯誤消息:

Expected null not to be null. 

我認爲當Chrome標籤沒有焦點,inputEl.focus()調用實際上並沒有被調用,但我不知道如何解決它。無論瀏覽器焦點如何,我寫過的所有其他單元測試都通過有沒有人遇到這個或有任何想法?

+0

今天遇到同樣的問題。不知道修復它的最優雅的方法是什麼。 – DevVersion

回答

1

爲角元素上觸發一個事件,您可以使用內置的JavaScript ES6方法dispatchEvent具有角的變化檢測機制的後續調用讓你的DOM更新爲:

inputElement.dispatchEvent(new Event('focus')); 
fixture.detectChanges(); 

更優雅的方式達到同樣的事情,就是用角的包裝方法:當你想設置一個值,你輸入元素

import { dispatchEvent } from '@angular/platform-browser/testing/src/browser_util' 

dispatchEvent(inputElement, 'focus'); 
fixture.detectChanges(); 

一個有趣的一個。您需要先串分配給輸入的數值屬性,然後觸發「輸入」更改事件:

inputElement.value = 'abcd'; 
dispatchEvent(inputElement, 'input'); 
fixture.detectChanges(); 

注:有一些不行動你可能期望的那樣的事件。例如,調度「點擊」事件不會將焦點放在您的輸入元素上!一種解決方法可能是第一個觸發「聚焦」事件,然後一個「click」事件如下:

dispatchEvent(inputElement, 'focus'); 
dispatchEvent(inputElement, 'input'); 
fixture.detectChanges(); 

所有的JavaScript事件here

+0

這應該是被接受的答案。 – willydee

相關問題