Angular 单元测试指令,参数为2+;
我有一个指令,它在鼠标悬停期间更改元素的背景色,如下所示Angular 单元测试指令,参数为2+;,angular,unit-testing,karma-jasmine,angular2-directives,mouseenter,Angular,Unit Testing,Karma Jasmine,Angular2 Directives,Mouseenter,我有一个指令,它在鼠标悬停期间更改元素的背景色,如下所示 import {Directive, ElementRef, HostListener, Input} from '@angular/core'; @Directive({ selector: '[appHighlightme]' }) export class HighlightmeDirective { @Input('appHighlightme') color : string constructor(privat
import {Directive, ElementRef, HostListener, Input} from '@angular/core';
@Directive({
selector: '[appHighlightme]'
})
export class HighlightmeDirective {
@Input('appHighlightme') color : string
constructor(private el:ElementRef) { }
@HostListener('mouseenter') onMouseEnter(){
this.highlight(this.color || 'yellow');
}
@HostListener('mouseleave') onMouseLeave(){
this.highlight('inherit');
}
highlight(color){
this.el.nativeElement.style.backgroundColor = color;
}
}
我试图为这个指令编写一个单元测试用例,如下所示
import { HighlightmeDirective } from './highlightme.directive';
import {ChangeDetectionStrategy, Component, DebugElement, ViewChild} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
@Component({
selector: 'my-test-component',
template: '<a [appHighlightme]="color" >test</a>'
})
export class TestComponent {
color:string = 'blue';
}
describe('HighlightmeDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
let inputEl: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
HighlightmeDirective
]
})
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
inputEl = fixture.debugElement.query(By.directive(HighlightmeDirective));
});
it('detect hover changes', () => {
inputEl.triggerEventHandler('mouseenter', {});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe(component.color);
inputEl.triggerEventHandler('mouseleave', {});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe('inherit');
});
it('should create an instance', () => {
const directive = new HighlightmeDirective(inputEl);
expect(directive).toBeTruthy();
});
});
从“/highlightme.directive”导入{HighlightmeDirective};
从'@angular/core'导入{ChangeDetectionStrategy,Component,DebugElement,ViewChild};
从“@angular/core/testing”导入{async,ComponentFixture,TestBed};
从“@angular/platform browser”导入{By}”;
@组成部分({
选择器:“我的测试组件”,
模板:“测试”
})
导出类TestComponent{
颜色:字符串='蓝色';
}
描述('highlightmedidirective',()=>{
let组件:TestComponent;
let夹具:组件夹具;
let inputEl:DebugElement;
在每个之前(()=>{
TestBed.configureTestingModule({
声明:[
测试组件,
强光直射
]
})
fixture=TestBed.createComponent(TestComponent);
组件=fixture.componentInstance;
inputEl=fixture.debugElement.query(By.directive(highlightmedidirective));
});
它('检测悬停变化',()=>{
triggerEventHandler('mouseenter',{});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe(component.color);
triggerEventHandler('mouseleave',{});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe('inherit');
});
它('应该创建一个实例',()=>{
const指令=新的HighlightmeDirective(输入);
expect(指令).toBeTruthy();
});
});
该指令在其他组件中运行良好。它接受ts文件中定义的颜色参数变量,并在悬停元素时将其用作bg颜色。但是当我尝试对相同的组件进行单元测试时,指令没有检测到从TestComponent传递的color参数,测试用例失败,并显示以下错误消息
错误:预期“黄色”为“蓝色”。-当黄色设置为默认悬停颜色时在触发任何事件之前,您需要确保
@Input('appHighlightme')颜色
属性已初始化。此初始化发生在第一个更改检测循环期间
因此,您应该触发更改检测,然后才触发mouseenter
事件。另一个观察结果是,由于您直接通过this.el.nativeElement.style.backgroundColor
操纵样式,所以您甚至不需要使用其他fixture.detectChanges()代码>呼叫
it('detect hover changes', () => {
fixture.detectChanges(); // !!! initialize 'color' property
inputEl.triggerEventHandler('mouseenter', {});
// fixture.detectChanges(); <-- useless here
expect(inputEl.nativeElement.style.backgroundColor).toBe(component.color);
inputEl.triggerEventHandler('mouseleave', {});
// fixture.detectChanges(); <-- useless here
expect(inputEl.nativeElement.style.backgroundColor).toBe('inherit');
});
it('detect hover changes',()=>{
fixture.detectChanges();/!!!初始化“颜色”属性
triggerEventHandler('mouseenter',{});
//fixture.detectChanges();您不需要跟踪指令上的事件处理程序。您需要在本机元素(在您的情况下为锚标记)上发出事件,指令处理程序将被自动调用。这是测试指令的实际方法
假设我们有一个带有类的锚标记,所以我们需要在这个标记上创建一个事件
@Component({
selector: 'my-test-component',
template: '<a class="mytag" [appHighlightme]="color" >test</a>'
})
export class TestComponent {
color:string = 'blue';
}
describe('HighlightmeDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
let inputEl: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
HighlightmeDirective
]
})
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges(); // trigger change detection so that UI renders and you can access element in next step.
inputEl = fixture.debugElement.query(By.css('.mytag'));
});
it('detect hover changes', () => {
inputEl.triggerEventHandler('mouseenter', {});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe(component.color);
inputEl.triggerEventHandler('mouseleave', {});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe('inherit');
});
it('should create an instance', () => {
const directive = new HighlightmeDirective(inputEl);
expect(directive).toBeTruthy();
});
});
@组件({
选择器:“我的测试组件”,
模板:“测试”
})
导出类TestComponent{
颜色:字符串='蓝色';
}
描述('highlightmedidirective',()=>{
let组件:TestComponent;
let夹具:组件夹具;
let inputEl:DebugElement;
在每个之前(()=>{
TestBed.configureTestingModule({
声明:[
测试组件,
强光直射
]
})
fixture=TestBed.createComponent(TestComponent);
组件=fixture.componentInstance;
fixture.detectChanges();//触发更改检测,以便UI呈现,并且您可以在下一步中访问元素。
inputEl=fixture.debugElement.query(By.css('.mytag'));
});
它('检测悬停变化',()=>{
triggerEventHandler('mouseenter',{});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe(component.color);
triggerEventHandler('mouseleave',{});
fixture.detectChanges();
expect(inputEl.nativeElement.style.backgroundColor).toBe('inherit');
});
它('应该创建一个实例',()=>{
const指令=新的HighlightmeDirective(输入);
expect(指令).toBeTruthy();
});
});
我希望它能对您有所帮助。只是一个猜测……也许需要更改检测周期,以便组件中有正确的颜色。我不确定这是否有任何意义,但您的测试代码显然是正确的。您可以尝试两件事:(1)使您的测试异步(fakeAsync),并尝试让时间流逝;(2)复制第一个fixture.detectChanges()
。在上面的注释中有一个输入错误:“它需要两个变化检测周期”…我尝试过fakeAsync。但是它不起作用('detect hover changes',fakeAsync(()=>{inputEl.triggerEventHandler('mouseenter',{});fixture.detectChanges();勾选(2000);预期(inputEl.nativeElement.style.backgroundColor).toBe(component.color);inputEl.triggerEventHandler('mouseleave',{});fixture.detectChanges();expect(inputEl.nativeElement.style.backgroundColor).toBe('inherit');});复制fixture.detectChanges()也不起作用