NodeJS 单元测试

NodeJS unit testing

可能是一个幼稚的问题,但我有一个 class 类似于(我的有更多的数据从数据库中读取并缓存它们):

var genericClass = class {

    constructor() {
        this.genericStructure = {};
    }

    async getState(key) {
        //some more core logic
        return this.genericStructure[key];
    }

    async putState(key, genericJson) {
        this.genericStructure[key] = genericJson;
        return true;
    }
}

它的 getStateputState 在消费者 class 中多次使用,我想在我的测试中从本地 map 对象模拟所有这些事件 class。可以吗?

我正在使用chai, mocha, sinon

"devDependencies": {
        "chai": "^4.1.2",
        "chai-as-promised": "^7.1.1",
        "eslint": "^4.19.1",
        "mocha": "^5.2.0",
        "nyc": "^12.0.2",
        "sinon": "^6.0.0",
        "sinon-chai": "^3.2.0"
    }

与其让你的 class 初始化它想要的结构,你应该提供(注入)它初始化时的结构。这就是依赖注入(构造函数注入)的原理。

var genericClass = class {

    constructor(initialStructure) {
        this.genericStructure = initialStructure;
    }

    async getState(key) {
        //some more core logic
        return this.genericStructure[key];
    }

    async putState(key, genericJson) {
        this.genericStructure[key] = genericJson;
        return true;
    }
}

现在在你的测试中你可以通过任何你喜欢的 initialStructure

更新答案

从您的评论来看,这个问题似乎有点令人困惑。我认为你需要的是模拟 class 方法以及更改它们的功能,同时支持依赖注入。您可以使用类似下面的内容 -

function testClassProxy(map) {

    let handleSetProps = function(args){
      map.set(args[0], args[1]);
      return true;
    }

    let handleGetProps = function(args){
      return map.get(args[0]);
    }

    let handler = {
        get(target, propKey) {
            return function (...args) {
                switch(propKey){
                  case 'setProps':{
                    return handleSetProps(args)
                  } 
                  case 'getProps': {
                    return handleGetProps(args)
                  }
                }
            };
        }
    };

    return new Proxy(map, handler);
}


let proxy = testClassProxy(new Map());


console.log(
  proxy.setProps('a', '1'),
  proxy.getProps('a')
);