我有一个像这样的组件
@Component({
selector: 'app-custom-form-control',
templateUrl: '<input>',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectComponent),
multi: true
}
]
})
export class CustomFormControlComponent implements ControlValueAccessor {...}
如您所见,它是一个自定义表单控件。我在一个我要测试的组件中使用它。
@Component({
selector: 'app-root',
templateUrl: '<div [formGroup]="form">
<app-custom-form-control formControlName="my_field"></app-custom-form-control>
</div>',
})
export class AppComponent implements OnInit, OnDestroy {...}
那么我如何模拟app-custom-form-control
进行测试呢?
当前的实施需要一个真实的组件......
beforeEach(async(() => {
const testRouter = new RouterStub();
const testDataService = new DataServiceStub();
TestBed.configureTestingModule({
declarations: [
AppComponent,
CustomFormControlComponent // it is a real stuff
],
imports: [
ReactiveFormsModule
],
providers: [
{ provide: Router, useValue: testRouter },
{ provide: DataService, useValue: testDataService }
],
schemas: [ NO_ERRORS_SCHEMA ]
}).compileComponents();
}));
否则(没有声明组件)我收到错误Failed: No value accessor for form control with name: app-custom-form-control
答案 0 :(得分:2)
在对Angular应用程序进行测试时,您可以遵循两种主要方法(和mix ):
1- Stubbing unneeded components,其中
(...)您创建并声明组件的存根版本 在测试中扮演很少或没有角色的指令(...)
(...)告诉Angular编译器忽略无法识别的元素和属性(...)
使用最后一个编译器,遇到app-custom-form-control
模板中的AppComponent
选择器时,编译器不会抛出错误。
3- Use both techniques together
选择一种或另一种方法,这取决于您,因为它取决于您在测试中的最终目标。
应用方法1将是这样的:
describe('AppComponent', () => {
// component stub
@Component({selector: 'app-custom-form-control', template: ''})
class CustomFormControlComponentStub {}
//...
beforeEach(async(() => {
const testRouter = new RouterStub();
const testDataService = new DataServiceStub();
TestBed.configureTestingModule({
declarations: [
AppComponent,
CustomFormControlComponentStub // it is fake! stuff
],
// ... code omitted
}).compileComponents();
}));
//...
});