【问题标题】:can't able to mock a variable while testing测试时无法模拟变量
【发布时间】:2020-09-16 23:38:45
【问题描述】:

我正在尝试在节点 js 上进行测试,我想在将要进行单元测试的函数之外模拟一个变量。 例如

const sample = [];
function uploadDoc {
sample.push('fileLocation')
}
function toSave(){
for (i=0;i<sample.length;i++)
**some process read and access doc
}

我在对第二个功能进行单元测试时遇到问题 我已经尝试重新连接 npm,但也无法正常工作

【问题讨论】:

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


    【解决方案1】:

    这样的编程可以,你应该先调用uploadDoc。

    const sample = [];
        function uploadDoc {
        sample.push('fileLocation')
    }
    function toSave(){
        uploadDoc();
        for (var i=0;i<sample.length;i++)
        **some process read and access doc
    }
    

    【讨论】:

    • 我需要用 sinon 测试代码。 uploadDoc() 和 toSave() 都是两个不同的 API
    【解决方案2】:

    好吧,您面临测试这两个功能的挑战,那么您需要重构代码。因为我认为,您的代码不可测试。 我给你这个很长的例子,它包含了你的两个函数,但都是可测试的。

    我为重构所做的更改:

    1. 函数 uploadDoc 现在将输出一个数组。
    2. 函数 toSave 现在需要 1 个参数,它是一个数组。
    3. combine functions into class.
    const sinon = require('sinon');
    const { expect } = require('chai');
    
    const Doc = {
      /**
       * @return array of file location.
       */
      uploadDoc: () => {
        const sample = [];
        sample.push('fileLocation');
        return sample;
      },
    
      /**
       * @param array samples
       * @return void
       */
      toSave: (samples) => {
        samples.forEach(() => {
          // Some process read and access doc.
        })
      },
    }
    
    /**
     * This is for example purposes.
     * @return void.
     */
    function integrationBothFunction () {
      const samples = Doc.uploadDoc();
      Doc.toSave(samples);
    }
    
    describe('Unit Test', function () {
      it('uploadDoc fn', function () {
        const result = Doc.uploadDoc();
        // You expect the result to be an array.
        expect(result).to.be.an('array');
      });
      it('toSave fn', function () {
        const samples = [];
        const spySamples = sinon.spy(samples, 'forEach');
        // Call the function
        Doc.toSave(samples);
        // You expect: there is forEach called for samples.
        expect(spySamples.calledOnce).to.equal(true);
        // Do not forget to restore.
        spySamples.restore();
      });
    
      it('integrationBothFunction fn', function () {
        // This is just sample to check.
        const testSample = ['x'];
        // Now finally, you can stub uploadDoc.
        // Where real uploadDoc function not get called.
        const stubUploadDoc = sinon.stub(Doc, 'uploadDoc');
        stubUploadDoc.returns(testSample);
    
        // Spy on toSave fn.
        const spyToSave = sinon.spy(Doc, 'toSave');
    
        integrationBothFunction();
    
        // You expect that toSave is processing output from uploadDoc.
        expect(stubUploadDoc.calledOnce).to.equal(true);
        expect(spyToSave.calledOnce).to.equal(true);
        // Check argument toSave.
        const { args } = spyToSave;
        expect(args).to.have.lengthOf(1);
        expect(args[0]).to.have.lengthOf(1);
        expect(args[0][0]).to.include(testSample[0]);
        // Restore spy and stub.
        stubUploadDoc.restore();
        spyToSave.restore();
      });
    });
    
    

    我是用 mocha 跑步的:

    $ npx mocha stackoverflow.js 
    
    
      Unit Test
        ✓ uploadDoc fn
        ✓ toSave fn
        ✓ integrationBothFunction fn
    
    
      3 passing (13ms)
    $ 
    

    希望这会有所帮助。祝你好运!

    【讨论】:

    • uploadDoc() 和 toSave() 都是两个不同的 API,已经返回对前端 @andreyunugro 的响应
    • 您能否解释更多相关的:两个不同的 API已经向前端返回响应?为了清楚起见,您可以编辑您的问题并添加更完整的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    相关资源
    最近更新 更多