2017-08-08 72 views
0

在我的單元測試中,我希望能夠用模擬元素替換元素併爲原始元素的方法提供存根。如何替換聚合物中的元素和存根方法

例如,假設我的組件的模板是這樣的:

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

讓後來在我的元素說,我做這樣的事情:

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

當我寫單元測試對於我的元素,我想做以下操作:

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

但我更喜歡事先總是嘲笑一切,以確保有從子元素來沒有副作用。

回答

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:() => null,然後在測試套件內的sinon.stub()調用中包裝該方法。

+0

感謝尼。您的第一個選擇是我以前的首選方式。但是,如果你在'ready()'或'attach()'回調中調用了一個來自子組件的方法,那麼你就不能嘲笑這樣的方法。 第二個選項也可以。也許這是最乾淨的。 謝謝 – jhuesos

0

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

它的工作原理,但只能使用一次執行的語句(作爲聚合物元件既不能註冊的,也沒有註冊的第二次),你可能需要更多的叫它比一次(例如,更改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)