【发布时间】:2020-06-05 14:04:11
【问题描述】:
我有一个下一个组件,其中包含在 Angular 9.1 上编写的注册表单
import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { FormBuilder, Validators, FormGroup, FormControl, FormGroupDirective, NgForm } from '@angular/forms';
@Component({
selector: 'app-sign-up-form',
templateUrl: './sign-up-form.component.html',
styleUrls: ['./sign-up-form.component.scss']
})
export class SignUpFormComponent implements OnInit {
@Output() submitedForm = new EventEmitter<any>();
@Input() accountExist = false;
public signUpForm: FormGroup;
public hidePassword = true;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.signUpForm = this.formBuilder.group({
email: [
'',
[
Validators.required,
Validators.pattern('^([A-z0-9_-]+\.)*[A-z0-9_-]+@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]{2,6}$')
]
],
passwords: this.formBuilder.group({
password: [
'',
[
Validators.required,
Validators.pattern('^[a-zA-Z0-9]{8,25}$'),
]
],
confirmedPassword: [
'',
[
Validators.required,
Validators.pattern('^[a-zA-Z0-9]{8,25}$'),
]
]
},
{
validators: [
this.validatePasswords,
Validators.required
]
}
)
});
}
public onSubmit() {
if (this.signUpForm.valid) {
this.submitedForm.emit(this.signUpForm.value);
}
}
public customErrorStateMatcher() {
return {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
if (form.submitted && control.parent.invalid) {
return true;
} else if (control.invalid && control.touched) {
return true;
} else {
return false;
}
}
};
}
private validatePasswords(group: FormControl) {
const password = group.get('password').value;
const confirmPass = group.get('confirmedPassword').value;
return password === confirmPass ? null : { notSame: true };
}
}
还有模板:
<div class="sign-up">
<h2 class="sign-up__header">Sign Up</h2>
<form class="sign-up__form"
[formGroup]="signUpForm">
<div class="sign-up__form-fields-container">
<mat-form-field class="sign-up__form-field"
hideRequiredMarker="true">
<mat-label>Email</mat-label>
<input placeholder="username@example.com"
matInput
formControlName="email" />
<mat-error *ngIf="signUpForm.get('email').hasError('required')">
You must enter a value
</mat-error>
<mat-error *ngIf="!signUpForm.get('email').hasError('required')">
Not a valid email
</mat-error>
</mat-form-field>
<div formGroupName="passwords">
<mat-form-field class="sign-up__form-field">
<mat-label style.color="white">Enter your password</mat-label>
<input matInput
formControlName="password"
[type]="hidePassword ? 'password' : 'text'" />
<mat-error *ngIf="signUpForm.get('passwords').get('password').hasError('required')">
You must enter a value
</mat-error>
<mat-error *ngIf="!signUpForm.get('passwords').get('password').hasError('required')">
Not a valid password
</mat-error>
<button type="button"
mat-icon-button
matSuffix
[attr.aria-label]="'Hide password'"
[attr.aria-pressed]="hidePassword"
(click)="hidePassword = !hidePassword">
<mat-icon *ngIf="!hidePassword">visibility</mat-icon>
<mat-icon *ngIf="hidePassword">visibility_off</mat-icon>
</button>
</mat-form-field>
<mat-form-field appearance="legacy"
class="sign-up__form-field">
<mat-label>Confirm password</mat-label>
<input matInput
type="password"
formControlName="confirmedPassword"
[errorStateMatcher]="customErrorStateMatcher()" />
<mat-error *ngIf="signUpForm.get('passwords').get('confirmedPassword').hasError('required')">
You must enter a value
</mat-error>
<mat-error *ngIf="this.signUpForm.get('passwords').get('confirmedPassword').value.length">
Password must match
</mat-error>
</mat-form-field>
</div>
</div>
<div class="sign-up__button-wrapper">
<button class="sign-up__submit"
(click)="onSubmit()"><span>SUBMIT</span></button>
<p *ngIf="accountExist"
class="sign-up__custom-error">Account already exist</p>
</div>
<div class="sign-up__account-exist">
<p class="sign-up__account-question">Already have an account ?</p>
<a class="sign-up__sign-in-link"
routerLink="/sign-in">Sign in</a>
<a mat-button
href="https://sportbuddies.herokuapp.com/oauth2/authorization/facebook"
class="sign-up__facebook-btn">
<span class="sign-up__facebook-icon"></span>
<span>Sign up with Facebook</span></a>
</div>
</form>
<div>
</div>
</div>
所以我正在使用 Jasmine/Karma 对其进行单元测试,以测试组件的创建、提交表单、验证。
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserModule, By } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { DebugElement } from '@angular/core';
import { SignUpFormComponent } from './sign-up-form.component';
describe('SignUpFormComponent', () => {
let component: SignUpFormComponent;
let fixture: ComponentFixture<SignUpFormComponent>;
let debug: DebugElement;
let el: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SignUpFormComponent ],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule
]
})
.compileComponents().then(() => {
fixture = TestBed.createComponent(SignUpFormComponent);
component = fixture.componentInstance;
debug = fixture.debugElement.query(By.css('form'));
el = debug.nativeElement;
});
}));
it('should create the form', () => {
fixture = TestBed.createComponent(SignUpFormComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it('should set submitted to true', async(() => {
component.onSubmit();
expect(component.signUpForm).toBeTruthy();
}));
it('should call the onSubmit method', async(() => {
fixture.detectChanges();
spyOn(component, 'onSubmit');
el = fixture.debugElement.query(By.css('button')).nativeElement;
el.click();
expect(component.onSubmit).toHaveBeenCalledTimes(0);
}));
it('form should be invalid', async(() => {
fixture.detectChanges();
component.signUpForm.controls['email'].setValue('');
component.signUpForm.controls['password'].setValue('');
component.signUpForm.controls['confirmedPassword'].setValue('');
expect(component.signUpForm.valid).toBeFalsy();
}));
it('form should be valid', async(() => {
component.signUpForm.controls['email'].setValue('hello@hello.com');
component.signUpForm.controls['password'].setValue('1234567F');
component.signUpForm.controls['confirmedPassword'].setValue('1234567F');
expect(component.signUpForm.valid).toBeTruthy();
}));
});
但它显示了我的错误
Failed: Cannot read property 'setValue' of undefined
和
Failed: Cannot read property 'controls' of undefined
和
Failed: Cannot read property 'valid' of undefined
那么,为什么这个 signUpForm 是未定义的,我该怎么办?谢谢。
【问题讨论】:
-
我不能 100% 确定,因为它需要调试但尝试添加 done();在你的 beforeEach then 中或将 then 转换为 await
标签: angular unit-testing jasmine karma-runner