【问题标题】:How to stub a required module in a class?如何在类中存根所需的模块?
【发布时间】:2019-11-08 12:11:30
【问题描述】:

我有一个使用我不想实际调用的数据库的类。在四处挖掘之后,我发现 Sinon 似乎解决了内部方法的这个问题,但我无法让它与所需的模块一起工作。我知道测试现在做的不多,但我想确认我可以在继续之前做这件事。

当我执行以下操作时,数据库不会被删除。

我要测试的代码如下所示:

const db = require('../../models');
const Op = db.Sequelize;

class UserSearch{

  async _resolveUserType(userType){
    let permission;
    if (typeof userType === 'number'){
      permission = await db.permission.findOne({ where: { id : userType } });
    }else{
      permission = await db.permission.findOne({ where: { type : userType } });
    }
    return permission;
  }
}

测试代码:

const db = require('../../models');
const { UserSearch } = require('./userSearch');

describe('UserSearch Test Suite', function(){
it('should return an object', async function(){
        const fakeDb = {
          permission: {
            findOne: function () {
              return new Promise(resolve => {
                return resolve({id: 3, type: 'student'})
              });
            }
          }
        };
        const userSearch = new UserSearch();
        sinon.stub(db, 'permission').returns(fakeDb.permission);
        const permission = await userSearch._resolveUserType(3);
        expect(permission).to.be.an('object');
      });
});

【问题讨论】:

    标签: node.js unit-testing chai sinon


    【解决方案1】:

    发现问题。在运行中检查 db.permission 对象后,我发现它没有 findOne 方法。它正在调用继承的 Model 类的 findOne 方法。通过删除权限,我删除了继承链接。

    我把存根改成

    sinon.stub(db.permission, 'findOne').returns(fakeDb.permission.findOne);

    一切正常。

    【讨论】:

      【解决方案2】:

      我不确定但很有趣。如果重写缓存怎么办?

      const { UserSearch } = require('./userSearch');
      
      describe('UserSearch Test Suite', function(){
      it('should return an object', async function(){
               require.cache[require.resolve('../../models')].exports = {
                permission: {
                  findOne: function () {
                    return new Promise(resolve => {
                      return resolve({id: 3, type: 'student'})
                    });
                  }
                }
              };
              const userSearch = new UserSearch();
              const permission = await userSearch._resolveUserType(3);
              expect(permission).to.be.an('object');
            });
      });
      

      【讨论】:

        【解决方案3】:

        先存根,然后调用要测试的函数:

        sinon.stub(db, 'permission').returns(fakeDb.permission);
        const userSearch = new UserSearch();
        const permission = await userSearch._resolveUserType(3);
        

        如果你用另一种方式做,那么它会调用非存根的原始函数。

        通常您在 beforeEach() 中设置存根并在测试套件中的 afterEach() 中进行清理。

        是的,您的印象是正确的,因为 sinon 非常适合在要测试的单元中删除外部依赖项。

        【讨论】:

          猜你喜欢
          • 2014-04-17
          • 2011-11-27
          • 1970-01-01
          • 2014-05-30
          • 2021-10-21
          • 2017-06-10
          • 1970-01-01
          • 1970-01-01
          • 2020-04-05
          相关资源
          最近更新 更多