Sinon如何在内部使用的类的函数

时间:2017-10-19 00:32:25

标签: javascript node.js unit-testing sinon

我想知道Sinon是否可以用于从内部调用的另一个类中存根函数。

例如,有一个dbutil类:

class DBUtils {
    getMyResult(var1, var2){
        return new Promise((resolve) => {
            console.log("calling real getMyResult");//I still see this in the log
            resolve(var1 + var2);
        });
    }
}
module.exports = DBUtils;

在另一个类dummyService中调用它:

const dbUtils = new DBUtils();
class dummyService {
    getResult(var1, var2){
    //initially in my code, it returns a promise, 
    //but I have replaced it with your code
    return dbUtils.getMyResult(var1, var2).then(item =>{
        console.log("finish getting my result!");
        console.log("here is my result: " + item);
        return item; 
    });
}
module.exports = dummyService;

这是我的单元测试文件:(由@Mark_M建议的应用代码更改)

describe("dummy Test", function () {
var service = new DummyService();

const stub = sinon.stub(DBUtils.prototype, 'getMyResult');
stub.resolves("1234");    

it("get result", function() {
    service.getResult("ab", "cd").then(item => {
        console.log(item);
    });
});
});

任何人都可以帮助我理解为什么我的Stub无效吗?如何在dbUtil类中存根getMyResult函数?

================解决方案===================

我错过了两件事:

  1. 我应该存根DBUtils.prototype
  2. sinon.stub(DBUtils.prototype, 'getMyResult').resolves("1234");
    
    1. 我在测试中导入DBUtils时出现错字。
    2. 在dummyService里面,我有

      const DBUtils = require(./dbutils);
      

      但是,在测试文件中,我有

      const DBUtils = require(./DBUtils);
      

      不知何故,sinon并没有抱怨它,这就是为什么我的存根从未注入原始方法的原因....在我的测试中更正导入后,我可以看到存根结果现在注入。

1 个答案:

答案 0 :(得分:1)

由于getMyResult()DBUtils类的类方法,因此您需要存根DBUtils的原型。像这样:

DBUtils.getMyResult()返回一个承诺。所以你不需要在dummyService.getResult()的承诺中重新包装它。如果你只是回复原来的承诺,它会更容易推理(和测试):

dummyService:

const DBUtils = require('./DBUtils')

class dummyService {
    getResult(var1, var2){
        const dbUtils = new DBUtils() // <- I assume you are making an instance somewhere
        return dbUtils.getMyResult(var1, var2).then(item =>{
            console.log("finish getting my result!");
            console.log("here is my result: " + item);
            return item // <- if you want to access item in then you need to return it
        });
    }
}
module.exports = dummyService;

现在在test.js:

const DBUtils = require('./DBUtils')
const DummyService = require('./dummy')
const sinon = require('sinon')

// stub the prototype
const stub = sinon.stub(DBUtils.prototype, 'getMyResult')
stub.resolves("Stubbed: 1234")

// make an instance of the service
const service = new DummyService()
service.getResult("ab", "cd").then(item => {
    console.log(item)
    // this prints 'stubbed: 1234'
    // item is "abcd", which is the returned value of the real getMyResult mothed
    // the expectation is, item should be "1234" as specified in the stub.
});