Я хочу выполнить юнит-тест для компонента входа. Я использую реактивные формы и Angular 7.
Я создал фальшивый бэкэнд-сервис, которому я звоню. Я пробовал код ниже, но я получаю следующую ошибку:
TypeError: Невозможно прочитать свойство 'debugElement' из неопределенного
Как вызвать метод входа и как подписать это значение?
Пожалуйста, кто-нибудь, помогите мне в этом.
signin.component.html
<form
class="form"
(ngSubmit)="onSubmit()"
[formGroup]="signinForm"
novalidate>
<div fxLayout="row wrap" fxLayout.xs="column" fxLayoutAlign="center center">
<div fxFlex="100" fxFlex.gt-md="25" fxFlex.gt-sm="25">
<mat-card>
<mat-card-header>
<mat-card-title class="_mat-title">
<h5>Sign In</h5>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<div
fxLayout="row wrap"
fxLayout.xs="column"
fxLayoutAlign="space-between stretch">
<div fxFlex="100" fxFlex.gt-md="100" fxFlex.gt-sm="100">
<mat-form-field>
<input
matInput
placeholder="Username(Email)"
formControlName="username"
value="{{username}}"
/>
<mat-error
*ngIf="submitted &&
!signinForm.controls['username'].errors?.required &&
signinForm.controls['username'].errors?.email &&
signinForm.controls['username'].dirty">
Please enter a valid email address
</mat-error>
<mat-error
*ngIf="submitted &&
signinForm.controls['username'].errors?.required &&
signinForm.controls['username']">
Email is required
</mat-error>
</mat-form-field>
</div>
<div fxFlex="100" fxFlex.gt-md="100" fxFlex.gt-sm="100">
<mat-form-field>
<input
matInput
placeholder="Password"
type="password"
formControlName="password"
value="{{password}}"
/>
<mat-error
*ngIf="submitted &&
signinForm.controls['password'].errors?.required &&
signinForm.controls['password']">
Password is required
</mat-error>
</mat-form-field>
</div>
<div fxFlex="100" fxFlex.gt-md="100" fxFlex.gt-sm="100">
<div class="_rem-me">
<mat-checkbox
color="primary"
class="_checkbox"
formControlName="ischeck">Remember me</mat-checkbox>
</div>
<div class="_forgot-link">
<a href="" class="_link">Forgot your username or password?</a>
</div>
</div>
</div>
</mat-card-content>
<mat-card-actions>
<div class="_button-row">
<button mat-raised-button color="primary">
Submit
</button>
</div>
</mat-card-actions>
</mat-card>
</div>
</div>
</form>
signin.component.ts
import {Component, OnInit, Input }from '@angular/core';
import {ErrorStateMatcher }from '@angular/material/core';
import {
FormControl,
FormGroup,
FormGroupDirective,
NgForm,
FormBuilder,
Validators
}from '@angular/forms';
import {SigninService }from '../../../services/signin/signin.service';
import {first }from 'rxjs/operators';
import {Router, ActivatedRoute }from '@angular/router';
/** Error when invalid control is dirty, touched, or submitted. */
@Component( {
selector:'ap-signin',
templateUrl:'./signin.component.html',
styleUrls:['./signin.component.scss']
})
export class SigninComponent implements OnInit {
// spinner
pageLoaded:boolean;
@Input()diameter = 64;
@Input()strokeWidth = 7;
signinForm:FormGroup;
username:string;
password:string;
returnUrl:string;
submitted = false;
accessRequestForm = false;
//ischeck = true;
// matcher = new MyErrorStateMatcher();
constructor(
private signinService:SigninService,
private route:ActivatedRoute,
private router:Router,
private fb:FormBuilder
) {
this.pageLoaded = false;
// redirect to dashboard if already signed in
if (this.signinService.currentUserValue) {
this.router.navigate(['/']);
}
}
ngOnInit() {
setTimeout(() => {
this.pageLoaded = true;
}, 500);
this.username = localStorage.getItem('username');
this.password = localStorage.getItem('password');
// Form validation
this.formValidation();
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
// Form validation
formValidation():void {
this.signinForm = this.fb.group( {
username:[null, [Validators.compose([Validators.required, Validators.email])]],
password:[null, [Validators.compose([Validators.required])]],
ischeck: [false, Validators.required]
});
}
get f() {
return this.signinForm.controls;
}
onSubmit() {
this.submitted = true;
//alert(this.f.ischeck.value);
if (this.signinForm.invalid) {
return;
}
this.pageLoaded = true;
this.signinService
.signin(this.f.username.value, this.f.password.value)
.pipe(first())
.subscribe(
data => {
if (this.f.ischeck.value) {
localStorage.setItem('username', this.f.username.value);
localStorage.setItem('password', this.f.password.value);
this.router.navigate([this.returnUrl]);
}else {
localStorage.clear();
this.router.navigate([this.returnUrl]);
}
},
err => {
this.pageLoaded = false;
});
}
}
signin.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { SigninComponent } from './signin.component';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from '../../core.module';
import { FeaturesModule } from '../../../features/features.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { SigninService, User } from '../../../services/signin/signin.service'
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
fdescribe('SigninComponent', () => {
let signinComponent: SigninComponent;
let signinService: SigninService;
let fixture: ComponentFixture<SigninComponent>;
let de: DebugElement;
let el: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
CoreModule,
FeaturesModule,
BrowserAnimationsModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule
],
declarations: [ ],
providers: [SigninService],
})
.compileComponents();
}));
beforeEach(() => {
const fixture = TestBed.createComponent(SigninComponent);
signinComponent = fixture.componentInstance;
//el = de.nativeElement;
fixture.detectChanges();
});
it('should create', () => {
expect(signinComponent).toBeTruthy();
});
it('should call auth signin method', () => {
let loginElement: DebugElement;
const debugElement = fixture.debugElement;
let signinService = debugElement.injector.get(SigninService);
let loginSpy = spyOn(signinService, 'signin').and.callThrough();
loginElement = fixture.debugElement.query(By.css('form'));
signinComponent.signinForm.controls['username'].setValue('test@hp.com');
signinComponent.signinForm.controls['password'].setValue('12345');
loginElement.triggerEventHandler('ngSubmit', null);
expect(loginSpy).toHaveBeenCalledTimes(1);
});
});