Angular 使用http服务调用对组件进行单元测试
首先,我是角度测试新手,所以请记住这一点。 我有一个组件在ngOnInit方法中调用服务。方法如下所示:Angular 使用http服务调用对组件进行单元测试,angular,unit-testing,Angular,Unit Testing,首先,我是角度测试新手,所以请记住这一点。 我有一个组件在ngOnInit方法中调用服务。方法如下所示: ngOnInit() { this.selectorService.category.subscribe(category => { if (!category) return; this.fieldService.list(category, false).subscribe(fields => { let ra
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);
}
// convenience getter for easy access to form fields
get f() {
return this.saveForm.controls;
}
我已经对每个服务设置和工作进行了测试。现在我想为这个组件编写测试。我试过这个:
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();
});
});
saveForm应该在ngOnInit方法中创建,从这一行可以看到:
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);
}
}
不是一个完整的解决方案,但像这样的。。。你仍然需要做产品服务。我在这里用茉莉花来制作模拟
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();
}));
beforeach(异步(()=>{
//设置模拟选择器服务
常量选择器服务={
category:new BehaviorSubject(new category())//new category()应该是您希望category返回的任何内容
}
//使用一个函数“list”设置模拟服务
const fieldService=jasmine.CreateSpyObj('fieldService',['list'])//使用一个函数'list'创建fieldService mock
fieldService.list.and.returnValue(of(fields));//不确定此处应返回什么类型的对象…从fieldService.list()返回的对象类型
TestBed.configureTestingModule({
导入:[ReactiveFormsModule、HttpClientTestingModule、SharedModule、ToAssetModule.forRoot()],
声明:[规范SAVEComponent],
提供程序:[ToAssetService,{Provider:FieldService,useValue:FieldService},{Provider:SelectorService,useValue:SelectorService}],
}).compileComponents();
}));