Создайте объект определенного типа, который возвращает true для instanceof, не используя new - PullRequest
0 голосов
/ 27 апреля 2020

В настоящее время я пишу юнит-тесты, и одна часть логики c проверяет, является ли элемент input определенного типа. Поскольку я использую angular, я не могу создать этот объект без серьезных накладных расходов. (Рассматриваемый объект - это MatSelect).

Теперь я хотел бы знать, если есть способ, просто определить объект и создать / привести и объект к этому указанному c 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 чек

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Основываясь на этом ответе: Повторно реализованный конструктор [Symbol.hasInstance], но он по-прежнему не будет называться

Я нашел следующий обходной путь:

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!

0 голосов
/ 27 апреля 2020

instanceof проверит фактический прототип MatSelect, поэтому вы не сможете получить его, чтобы он возвращал истину без фактического использования фактического класса MatSelect (или подкласса). Поскольку вы используете Angular, вы можете захотеть добавить в свой TestBed поддельный компонент MatSelect.

...