如何用 mocha chai 和 sinon 独立测试 javascript 功能?

How to test javascript function independently with mocha chai and sinon?

我是单元测试的新手,并且一直在阅读一些关于 javascript 实践的教程。我会用一个愚蠢的例子来解释我的问题。

假设 John 需要去上学,在知道他是否准备好去之前,他必须检查他是否有他的书包和耳机。这将使用以下函数调用:

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() 的模拟值。我说得对吗?

如果是这样,您能否提示我如何模拟这两个值?

这是一个例子:

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 中完成的)。这基本上用您可以控制的新函数(存根)替换了原来的函数。

根据测试,存根是"told"what to return每个函数(使用.returns()),调用isReadyToGo,检查其结果出乎意料。

每次测试后,stub都会恢复(意思是恢复原来的功能)