首先,我是角度测试的新手,所以请记住这一点。 我有一个在 ngOnInit 方法中调用服务的组件。该方法如下所示:
ngOnInit() {
this.selectorService.category.subscribe(category => {
if (!category) return;
this.fieldService.list(category, false).subscribe(fields => {
let rangeFields = fields.filter(field => !field.isSpecification);
let specificationFields = fields.filter(field => field.isSpecification);
this.fields = specificationFields;
this.productService.listValidatedRangeProducts(category).subscribe(range => {
if (!range.length) return;
this.products = range;
this.range = this.productModelService.mapProducts(rangeFields, range);
this.saveForm = this.toFormGroup(range[0]);
});
});
});
}
private toFormGroup(product: any): FormGroup {
let group: any = {};
this.fields.forEach(field => {
group[field.name] = new FormControl(product[field.name]);
});
return new FormGroup(group);
}
我已经为每个服务设置和工作进行了测试。现在,我要为此组件编写测试。我尝试过:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { SharedModule } from '@shared';
import { SpecificationsSaveComponent } from './specifications-save.component';
import { ToastrModule, ToastrService } from 'ngx-toastr';
describe('SpecificationsSaveComponent', () => {
let component: SpecificationsSaveComponent;
let fixture: ComponentFixture<SpecificationsSaveComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule, HttpClientTestingModule, SharedModule, ToastrModule.forRoot()],
declarations: [SpecificationsSaveComponent],
providers: [ToastrService],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SpecificationsSaveComponent);
component = fixture.componentInstance;
component.range = [
{
gtin: 0,
},
{
gtin: 1,
},
];
component.fields = [
{
id: 0,
canCopy: false,
categoryId: 'cameras',
dataType: 0,
display: false,
isSpecification: true,
name: 'gtin',
order: 0,
required: true,
},
];
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should save and get next', () => {
expect(component.saveForm.controls['gtin'].value).toBe(1);
});
it('should save and get reset', () => {
expect(component.saveForm.controls['gtin'].value).toBeNull();
});
});
基本上,我尝试设置公共属性,但是它不起作用。我收到此错误:
TypeError:无法读取未定义的属性“控件”
我怀疑这是因为有一个看起来像这样的吸气剂:
// convenience getter for easy access to form fields
get f() {
return this.saveForm.controls;
}
如以下行所示,应在 ngOnInit 方法中创建saveForm :
this.saveForm = this.toFormGroup(range[0]);
因此,看来我需要做的是模拟 selectorService , fieldService 和 productService ,然后再继续。 有人可以告诉我该怎么做吗?
这里是完整的组件:
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Field } from '@models';
import { SelectorService, ProductModelService } from '@core';
import { ProductService, FieldService } from '@services';
@Component({
selector: 'app-specifications-save',
templateUrl: './specifications-save.component.html',
styleUrls: ['./specifications-save.component.scss'],
})
export class SpecificationsSaveComponent implements OnInit {
range: any[];
saveForm: FormGroup;
fields: Field[];
submitted: boolean = false;
private products: any[];
constructor(
private fieldService: FieldService,
private productModelService: ProductModelService,
private productService: ProductService,
private selectorService: SelectorService,
) {}
ngOnInit() {
this.selectorService.category.subscribe(category => {
if (!category) return;
this.fieldService.list(category, false).subscribe(fields => {
let rangeFields = fields.filter(field => !field.isSpecification);
let specificationFields = fields.filter(field => field.isSpecification);
this.fields = specificationFields;
this.productService.listValidatedRangeProducts(category).subscribe(range => {
if (!range.length) return;
this.products = range;
this.range = this.productModelService.mapProducts(rangeFields, range);
this.saveForm = this.toFormGroup(range[0]);
});
});
});
}
// convenience getter for easy access to form fields
get f() {
return this.saveForm.controls;
}
onSubmit(): void {
this.submitted = true;
if (this.saveForm.invalid) {
return;
}
let categoryId = this.fields[0].categoryId;
let product = {
categoryId: categoryId,
};
let valid = true;
this.fields.forEach(field => {
let value = this.f[field.name].value;
if (valid) {
valid = !!value;
}
product[field.name] = value;
});
console.log(this.fields);
console.log(product);
console.log(valid);
// TODO: save the product
if (valid) {
let gtin = product['gtin'];
let index = 0;
this.range.forEach((item, i) => {
if (item.gtin !== gtin) return;
index = i;
});
console.log(gtin);
console.log(index);
this.saveForm = this.toFormGroup(this.range[index + 1]);
this.range.splice(index, 1);
}
// TODO: reset the form
}
private toFormGroup(product: any): FormGroup {
let group: any = {};
this.fields.forEach(field => {
group[field.name] = new FormControl(product[field.name]);
});
return new FormGroup(group);
}
}
答案 0 :(得分:0)
这不是一个完整的解决方案,但是类似这样的事情……您仍然需要进行产品服务。我在这里使用Jasmine来创建模拟。
beforeEach(async(() => {
//Setup mock selectorService
const selectorService = {
category: new BehaviorSubject<Category>(new Category()) //new Cateogry() should be whatever you want category to return
}
//Setup mock service with one function, 'list'
const fieldService = jasmine.CreateSpyObj('fieldService', ['list']) //Create fieldService mock with one function 'list'
fieldService.list.and.returnValue(of(fields)); //Not sure what type of object should be returned here... whatever type of object is returned form fieldService.list()
TestBed.configureTestingModule({
imports: [ReactiveFormsModule, HttpClientTestingModule, SharedModule, ToastrModule.forRoot()],
declarations: [SpecificationsSaveComponent],
providers: [ToastrService, {provide: FieldService, useValue: fieldService}, {provide: SelectorService, useValue: selectorService}],
}).compileComponents();
}));