【问题标题】:Create objct of certain type, which returns true for instanceof, without using new创建某种类型的对象,它对instanceof返回true,而不使用new
【发布时间】:2020-08-10 17:11:37
【问题描述】:

我目前正在编写单元测试,其中一部分逻辑是检查输入元素是否属于某种类型。由于我使用的是 angular,因此我无法在没有严重开销的情况下创建此对象。 (有问题的对象是一个 MatSelect)。

现在我想知道是否有办法,只定义一个对象并创建/转换和对象到这个特定的 tpye,而不使用 new

这是我要创建的对象的构造函数:

export declare class MatSelect ...     
constructor(_viewportRuler: ViewportRuler, _changeDetectorRef: ChangeDetectorRef, _ngZone: NgZone, _defaultErrorStateMatcher: ErrorStateMatcher, elementRef: ElementRef, _dir: Directionality, _parentForm: NgForm, _parentFormGroup: FormGroupDirective, _parentFormField: MatFormField, ngControl: NgControl, tabIndex: string, scrollStrategyFactory: any, _liveAnnouncer: LiveAnnouncer);

到目前为止,这是我累的:

const dummy = <MatSelect><unknown> {};
const dummy2 = {} as MatSelect;

两者都不满足instanceof检查

【问题讨论】:

  • 这就是 instanceof 在 javascript 中的工作方式。 Typescript 的类型断言(as&lt;&gt;)在编译时擦除,在运行时无效

标签: typescript jasmine karma-jasmine instanceof


【解决方案1】:

instanceof 将检查MatSelect 的实际原型,因此如果不实际使用实际的 MatSelect 类(或子类),您将无法让它返回 true。 由于您使用的是 Angular,因此您可能希望在您的 TestBed 中提供一个虚假的 MatSelect 组件。

【讨论】:

【解决方案2】:

基于此答案:Reimplemented Constructor[Symbol.hasInstance] but it still won't be called

我找到了以下解决方法:

it('testdummy', () => {
    // allows us tho define any object as MatSelect without the overhead of TestBed.createComponent
    // based on https://stackoverflow.com/a/40983417
    Object.defineProperty(MatSelect, Symbol.hasInstance, {
      value: function (instance) {
        return instance.isMatSelect;
      }
    });

    const directive = new SomeDirective(
      <MatFormField><unknown>{
        _elementRef: {nativeElement: 'test'},
        _control: {isMatSelect: true, openedChange: EMPTY}
    }, ...

这样定义时_control instanceof MatSelect返回true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 2021-01-30
    相关资源
    最近更新 更多