Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度5单元测试:如何使变更检测正常工作?_Angular_Angular5_Angular2 Testing_Angular2 Changedetection - Fatal编程技术网

Angular 角度5单元测试:如何使变更检测正常工作?

Angular 角度5单元测试:如何使变更检测正常工作?,angular,angular5,angular2-testing,angular2-changedetection,Angular,Angular5,Angular2 Testing,Angular2 Changedetection,如何使单元测试中的更改检测正常工作? 从来源来看,changeDetection应该在微任务为空(包括事件任务?)后运行 在这个简短的示例中,更改检测在setTimeout之后运行,但不是在手动单击元素之后运行。事件分派后是否有适当的方法触发更改检测(在fakeAsync区域内,没有fixture.detectChanges,因为在这种情况下,更改检测将与现实生活中的不同) 导入{ fakeAsync、tick、ComponentFixture、测试台、ComponentFixtureAutoD

如何使单元测试中的更改检测正常工作? 从来源来看,changeDetection应该在微任务为空(包括事件任务?)后运行

在这个简短的示例中,更改检测在setTimeout之后运行,但不是在手动单击元素之后运行。事件分派后是否有适当的方法触发更改检测(在fakeAsync区域内,没有fixture.detectChanges,因为在这种情况下,更改检测将与现实生活中的不同)

导入{
fakeAsync、tick、ComponentFixture、测试台、ComponentFixtureAutoDetect
}来自“角度/核心/测试”;
进口{
组件、QueryList、ViewChildren
}从“@angular/core”开始;
从“@angular/platform browser”导入{By}”;
从“@angular/common”导入{CommonModule};
描述('bug',()=>{
让主持人:主持人;
let夹具:组件夹具;
@组成部分({
选择器:'子',
模板:``,
})
类子{}
@组成部分({
模板:`
展示`
})
班主任{
shows=[假,假];
@ViewChildren(Child)children:QueryList;
构造函数(){
setTimeout(()=>this.shows[0]=true,50);
}
}
fit('test',fakeAsync(()=>{
TestBed.configureTestingModule({
进口:[
公共模块,
],
声明:[
主人,孩子,
],
供应商:[{
提供:ComponentFixtureAutoDetect,
useValue:true,
}]
});
fixture=TestBed.createComponent(主机);
主机=fixture.componentInstance;
勾选(10);
expect(主机、子机、长度)、toEqual(0);
勾选(50);
期望值(主人、孩子、身高)、toEqual(1);
const button=fixture.debugElement.query(By.css('button'));
triggerEventHandler('click',newevent('click');
勾选(50);
//fixture.detectChanges();
expect(host.children.length).toEqual(2);//此处失败
}));
});

我找到了问题的答案。 应使用
HTMLElement.dispatchEvent
。 如何触发
输入
键控
事件:

const inputDe = this.de.query(By.css('input'));
const inputEl = inputDe.nativeElement;
inputEl.value = text;
inputEl.focus(); // if it has matAutocompleteTrigger value accessor
inputEl.dispatchEvent(new Event('input'));
inputEl.dispatchEvent(new KeyboardEvent('keyup', {
      key: 'Enter',
}));
完整示例

import {
    fakeAsync, tick, ComponentFixture, TestBed, ComponentFixtureAutoDetect
} from '@angular/core/testing';
import {
    Component, QueryList, ViewChildren
} from '@angular/core';
import { By } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
fdescribe('bug', () => {
    let host: Host;
    let fixture: ComponentFixture<Host>;
    @Component({
        selector: 'child',
        template: ``,
    })
    class Child {}
    @Component({
        template: `
            <ng-container *ngFor="let show of shows">
                <child *ngIf="show"></child>
            </ng-container>
            <button (click)="shows[1] = true">show</button>`
    })
    class Host {
        shows = [false, false];
        @ViewChildren(Child) children: QueryList<Child>;
        constructor() {
            setTimeout(() => this.shows[0] = true, 50);
        }
    }
    it('test', fakeAsync(() => {
        TestBed.configureTestingModule({
            imports: [
                CommonModule,
            ],
            declarations: [
                Host, Child,
            ],
            providers: [{
                provide: ComponentFixtureAutoDetect,
                useValue: true,
            }]
        });
        fixture = TestBed.createComponent(Host);
        host = fixture.componentInstance;
        tick(10);
        expect(host.children.length).toEqual(0);
        tick(50);
        expect(host.children.length).toEqual(1);
        const button = fixture.debugElement.query(By.css('button'));
        button.nativeElement.dispatchEvent(new Event('click')); // proper way
        tick(50);
        expect(host.children.length).toEqual(2); // no fail now
    }));
});
导入{
fakeAsync、tick、ComponentFixture、测试台、ComponentFixtureAutoDetect
}来自“角度/核心/测试”;
进口{
组件、QueryList、ViewChildren
}从“@angular/core”开始;
从“@angular/platform browser”导入{By}”;
从“@angular/common”导入{CommonModule};
fdescribe('bug',()=>{
让主持人:主持人;
let夹具:组件夹具;
@组成部分({
选择器:'子',
模板:``,
})
类子{}
@组成部分({
模板:`
展示`
})
班主任{
shows=[假,假];
@ViewChildren(Child)children:QueryList;
构造函数(){
setTimeout(()=>this.shows[0]=true,50);
}
}
它('test',fakeAsync(()=>{
TestBed.configureTestingModule({
进口:[
公共模块,
],
声明:[
主人,孩子,
],
供应商:[{
提供:ComponentFixtureAutoDetect,
useValue:true,
}]
});
fixture=TestBed.createComponent(主机);
主机=fixture.componentInstance;
勾选(10);
expect(主机、子机、长度)、toEqual(0);
勾选(50);
期望值(主人、孩子、身高)、toEqual(1);
const button=fixture.debugElement.query(By.css('button'));
button.nativeElement.dispatchEvent(新事件('click');//正确方式
勾选(50);
expect(host.children.length).toEqual(2);//现在没有失败
}));
});
const inputDe = this.de.query(By.css('input'));
const inputEl = inputDe.nativeElement;
inputEl.value = text;
inputEl.focus(); // if it has matAutocompleteTrigger value accessor
inputEl.dispatchEvent(new Event('input'));
inputEl.dispatchEvent(new KeyboardEvent('keyup', {
      key: 'Enter',
}));
import {
    fakeAsync, tick, ComponentFixture, TestBed, ComponentFixtureAutoDetect
} from '@angular/core/testing';
import {
    Component, QueryList, ViewChildren
} from '@angular/core';
import { By } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
fdescribe('bug', () => {
    let host: Host;
    let fixture: ComponentFixture<Host>;
    @Component({
        selector: 'child',
        template: ``,
    })
    class Child {}
    @Component({
        template: `
            <ng-container *ngFor="let show of shows">
                <child *ngIf="show"></child>
            </ng-container>
            <button (click)="shows[1] = true">show</button>`
    })
    class Host {
        shows = [false, false];
        @ViewChildren(Child) children: QueryList<Child>;
        constructor() {
            setTimeout(() => this.shows[0] = true, 50);
        }
    }
    it('test', fakeAsync(() => {
        TestBed.configureTestingModule({
            imports: [
                CommonModule,
            ],
            declarations: [
                Host, Child,
            ],
            providers: [{
                provide: ComponentFixtureAutoDetect,
                useValue: true,
            }]
        });
        fixture = TestBed.createComponent(Host);
        host = fixture.componentInstance;
        tick(10);
        expect(host.children.length).toEqual(0);
        tick(50);
        expect(host.children.length).toEqual(1);
        const button = fixture.debugElement.query(By.css('button'));
        button.nativeElement.dispatchEvent(new Event('click')); // proper way
        tick(50);
        expect(host.children.length).toEqual(2); // no fail now
    }));
});