webentwicklung-frage-antwort-db.com.de

Funktionsweise von Materialkomponenten mit Karma beim Komponententest Angular

Ich habe ein angular CLI-Projekt eingerichtet. Ich habe ein Formular erstellt, das angular Materialkomponenten wie <md-card>.

Ich beginne gerade damit, meinen ersten Karma/Jasmine-Unit-Test zu schreiben, und folge dabei den Schritten in eckige Dokumente .

Dies ist meine Komponentenvorlage:

<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>

Dies ist meine Karma-Spezifikation:

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);
    });
});

An dieser Stelle versuche ich nur, den Basiseinheitentest auszuführen, bei dem der Titel ordnungsgemäß angezeigt wird.

Es treten jedoch viele materialspezifische Fehler auf. Mögen

Kein Anbieter für MdDialog.

Ich öffne ein MD-Dialogfeld, wenn ich auf einen Link klicke. Der Code befindet sich in der (ziemlich langen) .ts-Datei, aber das ist hier nicht das Problem.

Wo würde ich MdDialog im Testfeld hinzufügen? Wenn ich es zu Providern hinzufüge, erhalte ich die Fehlermeldung: "Kein Provider für Overlay". Ich weiß nicht, wie ich das beheben soll.

Kann ich Karma so konfigurieren, dass es zu Beginn alle wesentlichen Komponenten enthält?

Vielen Dank.

19
Snowman

Alle Anbieter werden durch Aufrufen von forRoot() auf dem Modul bereitgestellt

imports: [ MaterialModule.forRoot() ]

Für Versionen 2.0.0-beta.4 und später (seit die forRoot Methode entfernt wurde):

imports: [ MaterialModule ]

Für Versionen 2.0.0-beta.11 und später, da MaterialModule entfernt wurde, müssen Sie die Module, die Sie für Ihre Testfälle benötigen, selbst importieren:

imports: [ MatButtonModule, MatDialogModule ]
4
Paul Samsotha

Gegenwärtige Technik erfordert den individuellen Import von Angular Materialmodulen, da MaterialModule veraltet ist und wurde in 2.0.0-beta.11 entfernt :

import {
    MatButtonModule,
    MatIconModule
} from '@angular/material';

Fügen Sie dann die gleiche Liste wie beim Import in die TestBed-Konfiguration hinzu:

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [ ... ],
        imports: [
            MatButtonModule,
            MatIconModule,
            ...
        ],
        providers: [ ... ]
    })
        .compileComponents();
}));
10
isherwood

Ich habe heute auch damit zu kämpfen, und Sie müssen die erforderlichen Klassen selbst durch die Verwendung von Anbietern in Jasmin verspotten. Es ist ein Ärger und ich wünschte, es gäbe einen besseren Weg, aber zumindest keine Fehler mehr ...

Wenn jemand eine bessere Idee hat, klären Sie bitte den Rest der Community auf!

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();
  }));
1
Peter