我正在尝试对Angular 6中的“添加对象”(添加菜肴)组件进行单元测试。使用当前代码,我得到错误“无法读取未定义的属性'dishForm'”。 < / p>
那么,看来DishAddComponent是否未被识别为要测试的组件?有人可以帮我吗?预先感谢!
我还曾尝试过(除其他方法外)将async添加到beforeEach,如此处所述:Angular 2 Testing - Component Instance is undefined,但是它不起作用。
要进行单元测试的角组件:
export class DishAddComponent implements OnInit {
public dishForm: FormGroup;
constructor(private dishService: DishService,
private formBuilder: FormBuilder,
private router: Router) { }
ngOnInit() {
// define dishForm (with empty default values)
this.dishForm = this.formBuilder.group({
name: ['', [Validators.required, Validators.maxLength(30), Validators.pattern('[a-zA-Z :]*')]],
country: [''],
ingredients: this.formBuilder.array([]),
recipe: ['', [Validators.required, Validators.minLength(50)]],
}, { validator: CustomValidators.DishNameEqualsCountryValidator });
}
addIngredient(): void {
let ingredientsFormArray = this.dishForm.get('ingredients') as FormArray;
ingredientsFormArray.push(IngredientSingleComponent.createIngredient());
}
addDish(): void {
if (this.dishForm.dirty && this.dishForm.valid) {
let dish = this.dishForm.value;
this.dishService.addDish(dish)
.subscribe(
() => {
this.router.navigateByUrl('/dishes');
});
}
}
}
玩笑中的单元测试:
describe('DishAddComponent', () => {
let component: DishAddComponent;
let fixture: ComponentFixture<DishAddComponent>;
let formGroup: FormGroup;
let formBuilderMock: any;
let dishServiceMock: any;
beforeEach(() => {
formBuilderMock = {
group: jest.fn().mockName('formBuilderMock.group'),
array: jest.fn().mockName('formBuilderMock.array')
};
dishServiceMock = {
addDish: jest.fn().mockName('dishServiceMock.addDish')
};
TestBed.configureTestingModule({
imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule.withRoutes(routes)],
declarations: [ DishAddComponent, IngredientSingleComponent ],
providers:
[
{ provide: FormBuilder, useValue: formBuilderMock },
{ provide: FormGroup, useValue: formGroup },
{ provide: DishService, useValue: dishServiceMock }
]
});
fixture = TestBed.createComponent(DishAddComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('form invalid when empty', () => {
(console).log(component);
expect(component.dishForm.valid).toBeFalsy();
});
});
编辑: 如果我使用下面的代码,也会出现错误:
DishAddComponent›应该创建
期望(已接收).toBeTruthy()
收到:未定义
it('should create', () => {
expect(component).toBeTruthy();
});
答案 0 :(得分:2)
最后,我用下面的代码摆脱了“未定义的错误”。我需要模拟一个子组件并创建一个formbuilder实例。感谢您的提示!
describe('DishAddComponent', () => {
let component: DishAddComponent;
let fixture: ComponentFixture<DishAddComponent>;
let dishServiceMock: any;
// mock singleingredientcomponent
@Component({
selector: 'app-ingredient-single',
template: '<div></div>',
})
class MockSingleIngredientComponent {
@Input() public ingredientIndex: number;
@Input() public ingredient: FormGroup;
}
// create new instance of FormBuilder
const formBuilder: FormBuilder = new FormBuilder();
beforeEach(async(() => {
dishServiceMock = {
addDish: jest.fn().mockName('dishServiceMock.addDish'),
addIngredient: jest.fn().mockName('dishServiceMock.addIngredient')
};
TestBed.configureTestingModule({
imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule.withRoutes([])],
declarations: [ DishAddComponent, MockSingleIngredientComponent ],
providers:
[
{ provide: FormBuilder, useValue: formBuilder },
{ provide: DishService, useValue: dishServiceMock }
]
})
.compileComponents();
}));
beforeEach(() => {
// create component and test fixture
fixture = TestBed.createComponent(DishAddComponent);
// get test component from the fixture
component = fixture.componentInstance;
// ..
fixture.detectChanges();
});
// unit tests
it('should create', () => {
expect(component).toBeTruthy();
});
});
答案 1 :(得分:1)
尝试在configureTestingModule()之后添加compileComponents()来编译组件
TestBed.configureTestingModule({
imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule.withRoutes(routes)],
declarations: [ DishAddComponent, IngredientSingleComponent ],
providers:
[
{ provide: FormBuilder, useValue: formBuilderMock },
{ provide: FormGroup, useValue: formGroup },
{ provide: DishService, useValue: dishServiceMock }
]
})
.compileComponents();