Как правильно заглушить элемент при модульном тестировании компонента LitElement?

Я пытаюсь выполнить модульное тестирование компонентов LitElement. Пытаясь изолировать компоненты, я недоумевал, как на самом деле заглушить элементы. То есть я не могу найти решение, как заменить исправный элемент на полый.
В полимерном проекте на тему модульного тестирования упоминается, что мне не удалось найти определение функции replace(), чтобы увидеть детали реализации. Собственно, то, что описывается полимерным проектом в заголовке «Создание заглушек», - это то, что я ищу.

Файл определения элемента

      export class AppElement extends LitElement {
    render() {
        return html`
            <header-element class="header"></header-element>
            <div class="body">
                <menu-element></menu-element>
                <social-media-element></social-media-element>
                <contacts-element></contacts-element>
                <tap-list-element name="Fridge List" display="fridge"></tap-list-element>
                <tap-list-element route="tap" name="Tap List" display="tap" ></tap-list-element>
                <home-element></home-element>
                <about-us-element></about-us-element>
                <not-found-element></not-found-element>
            </div>
       `;
   }
}

Файл тестирования элемента

      describe("Test Case for the AppElement Component", function() {
beforeEach(() => {
    app = new AppElement();
    document.body.appendChild(app);
    shadow = app.shadowRoot;
    app.updateComplete.then(() => {
        const tapListStub = new TapListElementStub();
        const tapListNodes = shadow.querySelectorAll('tap-list-element');
        console.log(app);
        const tapListLength = tapListNodes.length;
        const tapListNode = tapListLength === 1 ? tapListNodes[0] : null;
        tapListNode.replaceWith(tapListStub);
    });
});

it("should have the node for tap-list replaced with a stub", function(done) {
    app.updateComplete.then(() => {
        const newTap: TapListElement = shadow.querySelector('tap-list-element');
        console.log(shadow);
        assert.strictEqual('Tap List Stub', newTap.name);
        done();
    })
});

Вот код оригинального TapListElement

      @customElement('tap-list-element')
export class TapListElement extends LitElement {
    private _menu: Menu;
    private _tapList: Section;
    private _bottleList: Section;

    @property()
    name: string = 'Tap List';

    @property({type: String, attribute: true})
    display: string;

    constructor() {
        super();
        super.connectedCallback();
    }
}

А вот и заглушка

      @customElement('tap-list-element')
export class TapListElementStub extends LitElement {

    @property()
    name: string = 'Tap List Stub';

    @property({type: String, attribute: true})
    display: string;

    constructor() {
        super();
        super.connectedCallback();
    }
}

Приносим извинения за возможные опечатки с отступами.

Когда я попробовал приведенный выше код, я получил сообщение об ошибке, что веб-компонент с таким именем «tap-list-element» уже был зарегистрирован. Я попытался удалить декоратор @customElement в TapListElementStub, но затем получил сообщение об ошибке, что был вызван Illegal Constructor. Кто-нибудь пробовал заглушить компоненты litElement? Я исхожу из фона Angular. Там вспомогательная библиотека TestBed настраивает модуль, и вы можете заменить любой компонент, если атрибуты остаются такими же, а имя компонента в декораторе такое же.

1 ответ

Первая ошибка скорее всего вызвана <tap-list-element>определяется дважды в двух версиях. Этого нельзя избежать, так как на данный момент пользовательские элементы не являются неопределяемыми (и, следовательно, переопределенными с другим классом). Удаление вызова регистрации, как вы пытались, не решает проблему, потому что компонент все равно будет создан с использованием исходного класса.

Самым простым решением было бы использовать другое имя тега (даже документы Polymer, которые вы процитировали, делают это). Если вам действительно нужно, чтобы имена тегов были одинаковыми, то я могу предложить заменить только некоторые свойства / методы исходного класса. В руководствах по тестированию OpenWC и Modern Web есть несколько частей ( 1, 2), посвященных этому.

Другие вопросы по тегам