【问题标题】:How to replace elements and stub methods in Polymer如何替换 Polymer 中的元素和存根方法
【发布时间】:2017-08-08 09:09:08
【问题描述】:

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

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

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

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

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

当我为我的元素编写单元测试时,我想做以下事情:

  1. 模拟整个&lt;my-other-element&gt;
  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
});

但我更喜欢总是提前模拟所有内容,以确保子元素没有副作用。

【问题讨论】:

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


    【解决方案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;
      });
    });
    

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

    编辑:在第二种方法失败的情况下,我将存根元素的方法设置为类似于method: () =&gt; null,然后将该方法包装在测试套件内的 sinon.stub() 调用中。

    【讨论】:

    • 谢谢本尼。您的第一个选择是我之前的首选方式。但是如果你在ready()attached() 回调中从子组件调用一个方法,你就不能像那样模拟这些方法。第二个选项也可能有效。也许那是最干净的。谢谢
    【解决方案2】:

    我尝试了第二种方法: Polymer({is: 'fake-child-el', method: sinon.stub;});

    它可以工作,但该语句只能执行一次(因为 Polymer 元素既不能取消注册也不能再次注册),并且您可能需要多次调用它(例如,更改 method's返回值)。要解决此问题,您可以执行以下操作:

    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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-21
      • 2015-08-11
      • 2021-09-16
      • 2012-01-18
      相关资源
      最近更新 更多