2016-07-15 80 views
0

我是单元测试新手,并且已经阅读了一些关于使用javascript的练习的教程。我会用一个愚蠢的例子来解释我的问题。如何用mocha chai和sinon独立测试javascript函数?

比方说,约翰需要上学,想知道他是准备去他要检查,如果他有他的袋子,他的耳机了。这与下面的函数调用:

john.isReadyToGo; 

的isReadtToGo()函数的一个角色目标的实现如下:

characher.isReadyToGo = function() { 
    return this.hasBag() && this.hasHeadPhones(); 
} 

characher.hasBag = function() { 
    // return true or false 
} 

characher.hasHeadPhones = function() { 
    //return true or false 
} 

现在,让我们说,我想测试此功能。在单元测试中,建议测试功能而不受其他功能的影响。这意味着在这种情况下,我将不得不测试三个函数,但character.isReadyToGo()函数需要为this.hasBag()和this.hasHeadPhones()模拟值。我对吗?

如果是这样,你能不能给我我怎么能嘲笑这两个值的提示?

回答

1

下面是一个例子:

let character = {}; 

character.isReadyToGo = function() { 
    return this.hasBag() && this.hasHeadPhones(); 
} 

character.hasBag = function() { 
    // return true or false 
} 

character.hasHeadPhones = function() { 
    //return true or false 
} 

const sinon = require('sinon'); 
const expect = require('chai').expect; 

describe('Is character ready?',() => { 

    beforeEach(() => { 
    sinon.stub(character, 'hasBag'); 
    sinon.stub(character, 'hasHeadPhones'); 
    }); 

    afterEach(() => { 
    character.hasBag.restore(); 
    character.hasHeadPhones.restore(); 
    }); 

    it("Not if they don't have a bag or headphones",() => { 
    character.hasBag.returns(false); 
    character.hasHeadPhones.returns(false); 
    expect(character.isReadyToGo()).to.be.false; 
    }); 

    it("Not if they have headphones but no bag",() => { 
    character.hasBag.returns(false); 
    character.hasHeadPhones.returns(true); 
    expect(character.isReadyToGo()).to.be.false; 
    }); 

    it("Not if they have a bag but no headphones",() => { 
    character.hasBag.returns(true); 
    character.hasHeadPhones.returns(false); 
    expect(character.isReadyToGo()).to.be.false; 
    }); 

    it("Yes, if they have a bag and headphones",() => { 
    character.hasBag.returns(true); 
    character.hasHeadPhones.returns(true); 
    expect(character.isReadyToGo()).to.be.true; 
    }); 

}); 

对于每个测试,此短截线character.hasBagcharacter.hadHeadphones(这在beforeEach完成)。这基本上用一个你可以控制的新功能(存根)替换原来的。

根据测试,存根被“告知”每个函数返回的内容(使用.returns()),调用isReadyToGo,并根据期望检查其结果。

每次测试后,存根被恢复(意味着原来的功能被恢复)。

+0

小细节 - 不应该是'.to.be.true();'而不是'.to.be.true;'? –

+0

@JoeWhite [no](http://chaijs.com/api/bdd/#true)= D – robertklep