Как заставить компоненты материалов работать с кармой в модульном тестировании Angular
У меня есть угловой проект CLI. Я создал форму, в которой используются угловые компоненты материала, например, <md-card>
.
Я только начинаю с написания своего первого юнит-теста Карма/Жасмин, следуя инструкциям в угловых документах.
Это мой компонент шаблона:
<md-card [ngClass]="'dialog-card'">
<md-card-title [ngClass]="'dialog-title'">
{{title}}
</md-card-title>
<md-card-content>
<form (ngSubmit)="login()" #loginForm="ngForm">
<md-input-container class="md-block">
<input md-input [(ngModel)]="user.email"
name="userEmail" type="email" placeholder="Email"
ngControl="userEmail"
required>
</md-input-container>
<br>
<md-input-container class="md-block">
<input md-input [(ngModel)]="user.password"
name="userPassword" type="password" placeholder="Password"
ngControl="userPassword"
required>
</md-input-container>
<br>
<tm-message msgText="Wrong username or password" *ngIf="showError"></tm-message>
<br>
<button md-button type="submit" [disabled]="!loginForm.form.valid">Login</button>
<p (click)="openForgotPasswordModal()">Forgot Password?</p>
</form>
</md-card-content>
Это моя спецификация кармы:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { MaterialModule, MdDialogRef, MdDialog } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { TmLoginComponent } from './tm-login.component';
import { TmMessageComponent } from '../../shared/components/tm-message.component';
import { UserAuthenticationService } from '../login/user-authentication.service';
describe('TmLoginComponent (inline template)', () => {
let comp: TmLoginComponent;
let fixture: ComponentFixture < TmLoginComponent > ;
let de: DebugElement;
let el: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TmLoginComponent, TmMessageComponent], // declare the test component
imports: [MaterialModule, FormsModule,
RouterTestingModule.withRoutes(
[{
path: 'login',
component: TmLoginComponent
}, ])
],
providers: [UserAuthenticationService],
});
fixture = TestBed.createComponent(TmLoginComponent);
comp = fixture.componentInstance; // TmLoginComponent test instance
// query for the title <h1> by CSS element selector
de = fixture.debugElement.query(By.css('.title'));
el = de.nativeElement;
});
it('should display original title', () => {
fixture.detectChanges();
expect(el.textContent).toContain(comp.title);
});
});
На данный момент я просто пытаюсь запустить базовый unit тест, чтобы заголовок отображался правильно.
Тем не менее, я получаю много материальных ошибок. подобно
Нет провайдера для MdDialog.
Я открываю диалог md при нажатии на ссылку. Код находится в (довольно длинном) файле .ts, но здесь проблема не в этом.
Где бы я добавил MdDialog в тестовом стенде? Если я добавляю его в провайдеры, я получаю ошибку: "нет провайдера для наложения". Я не знаю, как это исправить.
Можно ли как-то настроить карму для включения всех компонентов материала при запуске?
Благодарю.
Ответы
Ответ 1
Все провайдеры предоставляются путем вызова forRoot()
в модуле
imports: [ MaterialModule.forRoot() ]
Для версий 2.0.0-beta.4
и более поздних версий (так как метод forRoot
был удален):
imports: [ MaterialModule ]
Для версий 2.0.0-beta.11
и более поздних версий, так как MaterialModule
был удален, вам необходимо самостоятельно импортировать модули, необходимые для тестовых случаев:
imports: [ MatButtonModule, MatDialogModule ]
Ответ 2
Текущая техника требует индивидуального импорта Angular материальных модулей, поскольку MaterialModule
устарела и удалена в 2.0.0-beta.11:
import {
MatButtonModule,
MatIconModule
} from '@angular/material';
Затем добавьте тот же список, что и импорт в конфигурации TestBed:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ... ],
imports: [
MatButtonModule,
MatIconModule,
...
],
providers: [ ... ]
})
.compileComponents();
}));
Ответ 3
Я боролся с этим и сегодня, и вам нужно самим смоделировать необходимые классы, используя провайдеров в жасмине. Это хлопот, и я хотел бы, чтобы был лучший способ, но, по крайней мере, больше ошибок нет...
Если у кого-то есть идея получше, просвещайте остальную часть сообщества!
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AlertDialogComponent } from './alert-dialog.component';
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
describe('AlertDialogComponent', () => {
let component: AlertDialogComponent;
let fixture: ComponentFixture<AlertDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MatDialogModule],
declarations: [AlertDialogComponent],
providers: [
{
provide: MatDialogRef, useValue: {}
},
{
provide: MAT_DIALOG_DATA, useValue:{}
}
],
}).compileComponents();
}));