#angular #typescript #unit-testing #angular-material #karma-jasmine
#angular #typescript #модульное тестирование #angular-материал #карма-жасмин
Вопрос:
Я провожу некоторый модульный тест с jasmine и karma для приложения angular 6, которое проверяет, является ли поле FormGroup допустимым. У меня возникают проблемы с элементом управления мат-выбором. когда я запускаю тестовый пример, Karma выдает сообщение об ошибке Error: No value accessor for form control with name: 'importId'
. Кстати, компонент работает нормально, как я и ожидал.
Это мой компонент:
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material";
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
@Component({
selector: 'app-my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
modelForm: FormGroup;
imps;
constructor(
public dialogRef: MatDialogRef<MyComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
this.imps = data['imp'];
}
ngOnInit() {
this.modelForm = new FormGroup({
name: new FormControl(null, Validators.required),
importId: new FormControl(null, Validators.required),
});
}
}
Мой HTML-шаблон выглядит следующим образом:
<mat-dialog-content>
<form [formGroup]="modelForm">
<mat-form-field>
<input matInput
placeholder="Name"
formControlName="name">
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Source import"
formControlName="importId">
<mat-option *ngFor="let imp of imps" [value]="imp.uuid">
{{imp.label}}
</mat-option>
</mat-select>
</mat-form-field>
</form>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-raised-button color="primary" [disabled]="!modelForm.valid" (click)="someFakeFunction()">Create</button>
<button mat-raised-button (click)="dialogRef.close()">Cancel</button>
</mat-dialog-actions>
Наконец, это мой модульный тест:
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {MockMatDialogData, MockMatDialogRef} from '@testing/mock/material';
import {MyComponent} from './evaluation-wizard.component';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {NO_ERRORS_SCHEMA} from "@angular/core";
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
imports: [ReactiveFormsModule, FormsModule],
providers: [
{provide: MatDialogRef, useValue: MockMatDialogRef},
{provide: MAT_DIALOG_DATA, useClass: MockMatDialogData}
],
schemas: [NO_ERRORS_SCHEMA],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
component.ngOnInit();
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('Form validation', () => {
it('form invalid when empty ', function () {
expect(component.modelForm.valid).toBeFalsy();
});
it('name field validity ', () => {
let name = component.modelForm.controls['name'];
expect(name.valid).toBeFalsy();
let errors = {};
errors = name.errors || {};
expect(errors['required']).toBeTruthy();
name.setValue("test");
errors = name.errors || {};
expect(errors['required']).toBeTruthy();
});
});
});
Я не могу заставить это работать, какие-либо предложения, чего мне не хватает?
Комментарии:
1. Вы не импортируете модули материалов в свой модуль тестирования. Таким образом, mat-form-field, mat-select и т. Д. Просто Рассматриваются Angular как неизвестные элементы (поскольку вы сказали ему сделать это с помощью NO_ERRORS_SCHEMA).
2. @JBNizet, фантастика. это работает для меня. Я действительно ценю. Не стесняйтесь включать ответ в этот канал.
3. У меня была та же проблема, но с мат-флажком. Я добавил MatCheckboxModule в импорт тестового стенда, и это устранило ошибку, спасибо!
4. Для тех, кто использует
mat-button-toggle-group
, вам нужно будет добавитьMatButtonToggleModule
в свой тестовый стенд импорт, нет необходимостиNO_ERRORS_SCHEMA
илиBrowserAnimationsModule
Ответ №1:
Вы не импортируете модули материалов в свой модуль тестирования.
Итак mat-form-field
, mat-select
, и т. Д. Просто Рассматриваются Angular как неизвестные элементы (поскольку вы сказали ему сделать это с помощью NO_ERRORS_SCHEMA
).
Комментарии:
1. Работает как шарм. Кроме того, я включил
BrowserAnimationsModule
.2. Спас мой день. Спасибо!!
3. Использование
NO_ERRORS_SCHEMA
— плохая идея. Это замаскирует другие проблемы с вашими тестами. ИспользуйтеCUSTOM_ELEMENTS_SCHEMA
вместо этого. medium.com/@fivedicephoto /… объясняет немного больше, почему.
Ответ №2:
В моем случае я забыл
import {MatSelectModule} from '@angular/material/select';
в модуле.
Так что, если вы импортируете, это должно сработать.
Ответ №3:
Я думаю, вам не хватает некоторых важных модулей, поэтому они неизвестны компилятору Angular. Поместите в свой импорт как минимум следующее (и, я думаю, больше):
imports: [ReactiveFormsModule, FormsModule,
BrowserModule,
BrowserAnimationsModule,
MatSelectModule,
MatOptionModule,
MatInputModule
],
Используйте также
schemas: [CUSTOM_ELEMENTS_SCHEMA],
чтобы сообщить компилятору, чтобы он мог обнаруживать теги, отличные от HTML.
С этим исправлением вам не понадобится NO_ERRORS_SCHEMA
, который не следует использовать в этих простых случаях.