2017-02-02 150 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

相关问题