Как заменить элементы и методы заглушки в Polymer

1

В моих модульных тестах я хотел бы иметь возможность заменять элементы с издеваемыми элементами, а также предоставлять заглушки для методов исходного элемента.

Например, допустим, что шаблон моего компонента выглядит следующим образом:

<template>
   <my-other-element id="myOtherElement"></my-other-element>
</template>

Скажем позже, в моем элементе я делаю что-то вроде этого:

myMethod: function () {
   this.$.myOtherElement.foo();
}

Когда я пишу unit тест для своего элемента, я хотел бы сделать следующее:

  1. Откажитесь от всего <my-other-element>
  2. Предоставить метод заглушки для foo()

Я нашел способ добиться этого, но почему-то это не кажется очень чистым. Мое текущее решение следующее:

var fooStub;

beforeEach(function () {
    fooStub = sinon.stub();

    replace('my-other-element').with('fake-my-other-element');
    document.createElement('fake-my-other-element').constructor.prototype = {
        foo: fooStub
    };
    element = fixture('basic');
});  

Мне интересно, есть ли лучший способ достичь тех же результатов. Как-то создание пустого элемента, чтобы изменить свойство prototype для добавления заглушек, кажется, не лучший способ.

И я знаю, что вы также можете это сделать:

stub('my-other-element', {
    foo: fooStub
});

Но я предпочитаю всегда издеваться над всем, чтобы убедиться, что побочных эффектов от дочернего элемента нет.

Теги:
unit-testing
testing
polymer
polymer-2.x

2 ответа

1

есть несколько вариантов, которые я использовал. Одним из них является проактивное добавление этих методов к рассматриваемому элементу

chai.should();
suite('let\s stub a child method', () => {
  let testView;
  setup(() => {
    replace('child-el').with('fake-child-el');
    testView = fixture('basic');
    testView.$.child.method = sinon.stub();
  });

  test('myMethod() calls child method', () => {
    testView.myMethod();
    testView.$.child.method.should.have.been.called;
  });
});

Другим является создание поддельного элемента для заглушения и обертывания его методами

Polymer({is: 'fake-child-el', method: sinon.stub;});

chai.should();
suite('let\s stub a child method', () => {
  let testView;
  setup(() => {
    replace('child-el').with('fake-child-el');
    testView = fixture('basic');
  });

  test('myMethod() calls child method', () => {
    testView.myMethod();
    testView.$.child.method.should.have.been.called;
  });
});

Это может не работать во всех браузерах.

EDIT: в тех случаях, когда второй подход завершился неудачно, я сделал методы stub-element вроде method:() => null, а затем завернул этот метод в вызов sinon.stub() внутри набора тестов.

  • 0
    Спасибо Бенни. Ваш первый вариант был моим любимым способом раньше. Но если вы вызываете метод из дочернего компонента в обратных вызовах ready() или attached() , вы не можете смоделировать подобные методы. Второй вариант может также работать. Может быть, это самый чистый. Спасибо
0

Я попробовал второй метод: Polymer({is: 'fake-child-el', method: sinon.stub;});

Он работает, но оператор может быть выполнен только один раз (поскольку элемент Polymer не может быть ни незарегистрирован, ни зарегистрирован во второй раз), и вы можете вызвать его более одного раза (например, чтобы изменить возвращаемое значение method). Чтобы обойти это, вы можете сделать следующее:

let fakeChildEl;  
let replaceChildEl = (methodReturnVal) => {
  const methodStub = sandbox.stub().returns(methodReturnVal);
  fakeChildEl = Polymer({
    is: 'fake-child-el',
    method: methodStub,
  });
  replace('child-el').with('fake-child-el');

  replaceChildEl = (methodReturnVal) => {
    const methodStub = sandbox.stub().returns(methodReturnVal);
    fakeChildEl.prototype.method = methodStub;
    replace('child-el').with('fake-child-el');
  }
};

Тогда любой unit тест может вызвать replaceChildEl(variableReturnVal)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню