所以我对angular和web开发有些陌生。总的来说,所以我真的不知道在单元测试中我可以访问哪些内容。
我制作了一个需要一个名称和两个文件的表格。如果其中之一丢失或不遵守与其各自字段相关的条件,则用户无法提交表单。为此,我创建了一个名为myForm的表单组,其中包含每个表单控件(名称,originalImage,modifiedImage)的验证器
我认为我想出了如何测试名称有效性的方法,但是我没有找到一种方法来测试文件的有效性。有人告诉我,我可以模拟文件,但对我来说情况有点复杂。这是我要测试的列表:
这是我的代码:
game-form.component.ts
import { Component, OnInit} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-game-form',
templateUrl: './game-form.component.html',
styleUrls: ['./game-form.component.scss']
})
export class GameFormComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
name: ['', [
Validators.required,
Validators.minLength(4),
Validators.maxLength(10),
Validators.pattern("[^ @]*")
]],
originalImage: ['', [
Validators.required,
Validators.pattern("[^@]*(.bmp|.BMP)")
]],
modifiedImage: ['', [
Validators.required,
Validators.pattern("[^@]*(.bmp|.BMP)")
]],
});
}
public get name() {
return this.myForm.get('name');
}
public get originalImage() {
return this.myForm.get('originalImage');
}
public get modifiedImage() {
return this.myForm.get('modifiedImage');
}
public onFileChange(event:Event) {
const reader = new FileReader();
const files:FileList | null = (event.target as HTMLInputElement).files;
const file:File | null = (files != null)?files[0]:null;
const idControl:string = (event.target != null)?(event.target as HTMLInputElement)["id"]:"";
reader.onload = () =>
{
switch(idControl)
{
case "originalImage":
this.myForm.patchValue({
originalImage : reader.result
});
break;
case "modifiedImage":
this.myForm.patchValue({
modifiedImage : reader.result
});
break;
}
};
if(file != null)
{
reader.readAsDataURL(file);
}
}
}
game-form.component.spec.ts
import { async, ComponentFixture, TestBed} from "@angular/core/testing";
import { GameFormComponent } from "./game-form.component";
import { MatIconModule } from "@angular/material/icon";
import { ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule, MatInputModule } from '@angular/material';
import { AppComponent } from '../app.component';
import { RouterModule } from '@angular/router';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
describe('GameFormComponent', () => {
let component: GameFormComponent;
let fixture: ComponentFixture<GameFormComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
GameFormComponent,
AppComponent
],
imports:[
RouterModule,
ReactiveFormsModule,
MatFormFieldModule,
MatInputModule,
BrowserAnimationsModule,
MatIconModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GameFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
it('should not allow a form when empty', () => {
expect(component.myForm.valid).toBeFalsy();
});
it('should accept the name in the form', () => {
let name = component.myForm.controls['name'];
// 4 <= number of characters <= 10 (correct)
name.setValue("test");
let errors = name.errors || {};
expect(errors['required']).toBeFalsy();
expect(errors['minlength']).toBeFalsy();
expect(errors['maxlength']).toBeFalsy();
expect(errors['pattern']).toBeFalsy();
});
it('should not accept the name in the form since too many characters are entered', () => {
// 10 < number of characters (incorrect)
let name = component.myForm.controls['name'];
name.setValue("12345678900");
let errors = name.errors || {};
expect(errors['required']).toBeFalsy();
expect(errors['minlength']).toBeFalsy();
expect(errors['maxlength']).toBeTruthy();
expect(errors['pattern']).toBeFalsy();
});
it('should not accept the name in the form since few characters are entered', () => {
// 4 > number of characters (incorrect)
let name = component.myForm.controls['name'];
name.setValue("123");
let errors = name.errors || {};
expect(errors['required']).toBeFalsy();
expect(errors['minlength']).toBeTruthy();
expect(errors['maxlength']).toBeFalsy();
expect(errors['pattern']).toBeFalsy();
});
it('should not accept the name in the form since spaces are entered', () => {
// spaces (incorrect)
let name = component.myForm.controls['name'];
name.setValue(" 1");
let errors = name.errors || {};
expect(errors['required']).toBeFalsy();
expect(errors['minlength']).toBeFalsy();
expect(errors['maxlength']).toBeFalsy();
expect(errors['pattern']).toBeTruthy();
});
it('should not accept the name in the form since nothing is entered', () => {
// nothing (incorrect)
let name = component.myForm.controls['name'];
name.setValue("");
let errors = name.errors || {};
expect(errors['required']).toBeTruthy();
});
it('should not accept the original image since she has not been choosen', () => {
// the user hasn't choose an original image yet
let image = component.myForm.controls['originalImage'];
let errors = image.errors || {};
expect(errors['required']).toBeTruthy();
});
it('should not accept the modified image since she has not been choosen', () => {
// the user hasn't choose an modified image yet
let image = component.myForm.controls['modifiedImage'];
let errors = image.errors || {};
expect(errors['required']).toBeTruthy();
});
});
我不知道这是否对您有帮助(对我有帮助),但我也在我的html文件中发布了邮件:
game-form.component.html
<form [formGroup]="myForm" (ngSubmit) ="onSubmit()">
<mat-form-field class="example-full-width">
<input matInput placeholder="Game name" [value]="" formControlName="name">
<mat-error *ngIf="name.errors?.minlength && name.touched">
The name entered should at least contain 4 letters
</mat-error>
<mat-error *ngIf="name.errors?.maxlength && name.touched">
The name entered should at most contain 10 letters
</mat-error>
<mat-error *ngIf="name.errors?.pattern && name.touched">
The name entered must contain spaces
</mat-error>
</mat-form-field>
<br><br/>
<br><br/>
<mat-form-field class="example-full-width">
<input matInput placeholder="Original image" disabled value="No file selected" name="fist_entry" id="first_entry">
<div class="example-button-row">
<button (click)="originalImageInput.click()" mat-icon-button >
<mat-icon matSuffix>folder</mat-icon>
</button>
</div>
<input hidden (change)="onFileChange($event)" #originalImageInput type="file" accept = ".bmp" id="originalImage"
formControlName = "originalImage"
onchange="document.getElementById('first_entry').value = this.value.split('\\').pop().split('/').pop()">
<div class="error-message" *ngIf="originalImage.errors?.pattern">
The type of the file entered isn't ".bmp"
</div>
</mat-form-field>
<img [src]="this.myForm.get('originalImage').value" *ngIf="originalImage" class="image" id="originalImage" style="width:150px">
<br><br/>
<br><br/>
<br><br/>
<br><br/>
<mat-form-field class="example-full-width">
<input matInput placeholder="Modified Image" disabled value="No file selected" name="second_entry" id="second_entry">
<div class="example-button-row">
<button (click)="modifiedImageInput.click()" mat-icon-button >
<mat-icon >folder</mat-icon>
</button>
</div>
<input hidden (change)="onFileChange($event)" #modifiedImageInput type="file" accept= ".bmp" id="modifiedImage"
formControlName = "modifiedImage"
onchange="document.getElementById('second_entry').value = this.value.split('\\').pop().split('/').pop()">
<div class="error-message" *ngIf="modifiedImage.errors?.pattern">
The type of the file entered isn't ".bmp"
</div>
</mat-form-field>
<img [src]="this.myForm.get('modifiedImage').value" *ngIf="modifiedImage" class="image" id="modifiedImage" style="width:150px">
<br><br/>
<div id="submitPosition">
<button mat-button color="primary" type="submit" id="submit" [disabled]="myForm.invalid">Submit</button>
</div>
</form>
预先感谢您的帮助(或者至少是您的时间),希望我能找到解决方案并进一步了解Angular上的测试。