如何用mocha chai和sinon独立测试javascript函数?

时间:2016-07-15 18:09:53

标签: node.js unit-testing mocha sinon chai

我是单元测试的新手,并且已经使用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 个答案:

答案 0 :(得分: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,并根据期望检查其结果。

每次测试后,存根都会恢复(意味着原始功能已恢复)。