gpt4 book ai didi

angular - 如何在 Angular 组件中测试 ViewChild/ContentChild 属性?

转载 作者:行者123 更新时间:2023-12-04 01:38:58 25 4
gpt4 key购买 nike

我有一个用于正确显示验证错误的表单容器。我通过 ContentChild 装饰器访问表单控件并被动地操作它以构建验证消息。

我的问题是:如何正确地对这样的组件进行单元测试?

组件.ts

import { Component, ContentChild, Input, AfterContentInit } from '@angular/core';
import { FormControlName } from '@angular/forms';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/map';

@Component({
selector: 'app-form-group',
templateUrl: './form-group.component.html',
styleUrls: ['./form-group.component.scss'],
})
export class FormGroupComponent implements AfterContentInit {

@Input()
errorMessages: { [key: string]: string } = { };

@ContentChild(FormControlName)
control: FormControlName;

message: Observable<string>;
success: Observable<boolean>;
error: Observable<boolean>;

private buildErrorMessage(status): string {
if (status === 'INVALID' && this.control.touched && this.control.dirty) {
return Object.keys(this.control.errors)
.map(errorKey => this.errorMessages[errorKey])
.join('\n');
}
}

ngAfterContentInit() {
const delayedStatusChanges = this.control.statusChanges
.debounceTime(500);

this.message = delayedStatusChanges
.map(status => this.buildErrorMessage(status));
this.success = delayedStatusChanges
.map(status => status === 'VALID' && this.control.touched && this.control.dirty);
this.error = delayedStatusChanges
.map(status => status === 'INVALID' && this.control.touched && this.control.dirty);
}
}

我只是使用状态更改来更新我的样式。还可以在失败的情况下显示所有验证消息。

组件.html
<div
class="form-group"
[class.has-success]="success | async"
[class.has-error]="error | async"
>

<ng-content></ng-content>

<div
class="help-block"
[hidden]="message | async"
>
<i class="fa fa-remove"></i>
{{ message | async }}
</div>

</div>

组件规范
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { FormGroupComponent } from './form-group.component';

describe('FormGroupComponent', () => {
let component: FormGroupComponent;
let fixture: ComponentFixture<FormGroupComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
FormGroupComponent,
],
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(FormGroupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

最佳答案

为了向测试组件提供内容投影,可以在另一个包装器组件中编译它。

考虑到所需的 ContentChild指令( FormControlName )可以在没有表单组夹具的情况下存在:

@Component({
template: `<app-form-group><input [formControlName]></app-form-group>`
})
class WrapperComponent {}

测试台应包含指令和组件:
TestBed.configureTestingModule({
declarations: [FormGroupComponent, WrapperComponent, FormControlName]
})

预计该属性将是 FormControlName 的实例。指令类,可以查询和断言被测试的组件:
fixture = TestBed.createComponent(WrapperComponent);
fixture.detectChanges();

const wrapperCompDE = fixture.debugElement;
const testedCompDE = wrapperCompDE.query(By.directive(FormGroupComponent));
const testedComp = testedCompDE.componentInstance;
const inputDE = testedCompDE.query(By.css('input'));
const contentChild = inputDE.injector.get(FormControlName);

expect(contentChild instanceof FormControlName).toBe(true);
expect(testedComp.control).toBe(contentChild);

可以添加中间断言来品尝。

关于angular - 如何在 Angular 组件中测试 ViewChild/ContentChild 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48252766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com