如何替换Polymer

时间:2017-08-08 09:09:08

标签: javascript unit-testing testing polymer polymer-2.x

在我的单元测试中,我希望能够用模拟元素替换元素,并为原始元素的方法提供存根。

例如,假设我的组件的模板是这样的:

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

让我们稍后在我的元素中说我做这样的事情:

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

当我为我的元素编写单元测试时,我想执行以下操作:

  1. 模拟整个<my-other-element>
  2. foo()
  3. 提供存根方法

    我找到了实现这一目标的方法,但不知怎的,它看起来并不是很干净。我目前的解决方案如下:

    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
    });
    

    但我更愿意提前模拟所有内容,以确保子元素没有副作用。

2 个答案:

答案 0 :(得分: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;
  });
});

这可能不适用于所有浏览器。

编辑:在第二种方法失败的情况下,我使得stub-element的方法类似于method: () => null,然后将该方法包装在测试套件内的sinon.stub()调用中。

答案 1 :(得分: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');
  }
};

然后任何单元测试都可以调用replaceChildEl(variableReturnVal)