Angular-如何使用自定义输入组件子级测试容器组件?

时间:2019-01-14 12:37:17

标签: angular forms unit-testing

问题

我有一个使用自定义输入组件的容器组件。在服务期间或构建之后,它都可以正常工作,但是在测试中不起作用。

这是我得到的错误: An unhandled exception occurred while processing the request. ProtocolException: The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.


这是我文件的简化版本:

模板

Error: No value accessor for form control with name: 'name'

测试

<app-modal>
  <form [formGroup]="myForm" novalidate>
    <app-input formControlName="name"></app-input>
  </form>
</app-modal>

我也尝试过:使用@Component({ selector: 'app-input', template: '' }) class InputStubComponent {} beforeEach(async(() => { TestBed.configureTestingModule({ schemas: [ NO_ERRORS_SCHEMA ], declarations: [ InputStubComponent ], imports: [ ReactiveFormsModule, ] }) .compileComponents(); })); 而不声明组件。

1 个答案:

答案 0 :(得分:0)

有两种解决方法:

推荐
1)您可以从ReactiveFormsModule属性中删除imports,并将FormBuilder添加到providers属性中。 ReactiveFormsModule添加了formGroupformControlName伪指令,它们在模板级别进行检查。

这是您示例中的样子:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    schemas: [ NO_ERRORS_SCHEMA ],
    declarations: [
      InputStubComponent
    ],
    providers: [
      FormBuilder
    ]
  })
  .compileComponents();
}));

2)如果要测试子组件或保留ReactiveFormsModule,请使用以下函数创建带有值访问器的准系统存根组件:

const createAccessorComponent = (selector) => {
  @Component({
    selector: selector,
    template: '',
    providers: [
      {
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => AccessorComponent),
        multi: true,
      },
    ],
  })
  class AccessorComponent implements ControlValueAccessor {
    writeValue(obj: any): void {}
    registerOnChange(fn: any): void {}
    registerOnTouched(fn: any): void {}
    setDisabledState(isDisabled: boolean): void {}
  }

  return AccessorComponent;
};

您可以通过以下方式使用它:

const InputStubComponent = createAccessorComponent('app-input');

beforeEach(async(() => {
  TestBed.configureTestingModule({
    schemas: [ NO_ERRORS_SCHEMA ],
    declarations: [
      InputStubComponent
    ],
    imports: [
      ReactiveFormsModule,
    ]
  })
  .compileComponents();
}));