首页 > 解决方案 > 我正在尝试使用 Sinon 存根和模拟来测试我的函数,但我收到了一个错误。请建议我正确的写作技巧

问题描述

在这个模块中,我想测试调用其他模块的 findAll 函数的 searchAll 函数,所以我试图存根其他模块的 findAll 函数并模拟我的 test.js 模块中的 res。

使用ControllerModule.js

exports.searchAll = (req, res) => {
    Users.findAll((err, data) => {
        if (err)
            res.status(500).send({
                message: err.message || "Some error occured while retrieving data",
            });
        else res.send(data);
    });
};

另一个模块的 findAll 函数具有userid已被存根的参数。

因此,在存根并获得响应值之后,我试图在这里模拟响应,但它没有运行。模拟验证导致错误。如果我删除验证,测试用例会通过,但不会增加任何测试覆盖率。

测试.js

describe("searchAll", function() {
    let res;

    beforeEach(() => {
        res = {
            json: function() {},
        };
    });

    it("should return all the id's of  members of the club", async function() {
        const stubvalue = {
            userid: faker.random.uuid(),
        };
        const mock = sinon.mock(res);
        mock.expects("json").withExactArgs({
            data: stubValue
        });

        const stub = sinon.stub(UserModel, "findAll").returns(Stubvalue);
        const user = await UserController.searchAll();
        expect(stub.calledOnce).to.be.true;
        mock.verify();
        stub.restore();

    });
});

标签: javascriptnode.jsmockingmocha.jssinon

解决方案


您应该使用stub.callsFake(fakeFunction);UserModel.findAll()方法提供假实现。它接受一个回调参数,因此您需要stubvalue手动执行它并在您的假实现中将其传递给该回调。

UseControllerModule.js

const Users = require('./UserModel');

exports.searchAll = (req, res) => {
  Users.findAll((err, data) => {
    if (err) {
      res.status(500).send({
        message: err.message || 'Some error occured while retrieving data',
      });
    } else {
      res.send(data);
    }
  });
};

UserModel.js

module.exports = {
  findAll(callback) {
    console.log('real implementation');
    callback(null, 'real data');
  },
};

UseControllerModule.test.js

const sinon = require('sinon');
const { expect } = require('chai');
const UserModel = require('./UserModel');
const UserController = require('./UseControllerModule');

describe('searchAll', function () {
  let res;

  beforeEach(() => {
    res = {
      send: function () {},
    };
  });

  it("should return all the id's of  members of the club", async function () {
    const stubvalue = {
      userid: '123',
    };
    const mock = sinon.mock(res);
    mock.expects('send').withExactArgs(stubvalue);

    const stub = sinon.stub(UserModel, 'findAll').callsFake((callback) => {
      callback(null, stubvalue);
    });
    UserController.searchAll({}, res);
    expect(stub.calledOnce).to.be.true;
    mock.verify();
    stub.restore();
  });
});

单元测试结果:

  searchAll
    ✓ should return all the id's of  members of the club


  1 passing (6ms)

------------------------|---------|----------|---------|---------|-------------------
File                    | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------------------|---------|----------|---------|---------|-------------------
All files               |   66.67 |       25 |   66.67 |   66.67 |                   
 UseControllerModule.js |   83.33 |       25 |     100 |   83.33 | 6                 
 UserModel.js           |   33.33 |      100 |       0 |   33.33 | 3-4               
------------------------|---------|----------|---------|---------|-------------------

推荐阅读