如何测试这种依赖性?

时间:2018-01-11 10:55:34

标签: javascript node.js unit-testing dependency-injection tdd

背景

我正在尝试测试一个简单的缓存模块,但在注入依赖项时,我看不到保持API不变的方法。

代码

const myCache = () => {
    //this is a dependency. 
    //Ideally I would inject it ( a map already created), but if I do it, I will loose connect !
    let map; 

    const connect = url => {
        map = new Map();
       console.log(`This url ${url} exists for illustration purposes only!`);
    };

    const get = key => {
        console.log(`You requested an object with key: ${key}`);
        return map.get(key);
    };


    const set = ( key, value ) => {
        ma.set(key, value);
        console.log(`You want to save value ${value} with key ${key}`);
    };

    return {
        connect,
        get,
        set
    };
};

module.exports.myCache =  myCache;

这是一个使用地图的简单缓存模块,用于演示目的。 在此示例中,我有一个变量map,在我调用connect时会分配该变量。

问题

这里的问题是我需要知道是否使用正确的参数调用了map中的方法getset

因为map是在运行connect之后设置的,所以我无法监视它(例如使用sinonjs)。一个可能的解决方案是已经内置到myCache中的地图,但是API会改变,这是我想要避免的。

问题

我如何测试是否使用正确的参数调用map中的方法而不更改此模块的API?

2 个答案:

答案 0 :(得分:1)

  

在注入依赖项时,我看不到保持API不变的方法。

通常,您不会保持API不变。会发生什么是您扩展 API以允许更精细的控制。

const connect = url => {
    map = new Map();
   console.log(`This url ${url} exists for illustration purposes only!`);
};

为了让客户端控制地图,我们创建了一个接受地图作为参数的函数的新版本

const connect_v2 = url, injected_map => {
    map = injected_map;
   console.log(`This url ${url} exists for illustration purposes only!`);
};

然后,您可以通过让旧地图调用新地图来删除重复项,而无需更改其API

const connect = url => {
   connect_v2(url, new Map())
};

const connect_v2 = url, injected_map => {
   map = injected_map;
   console.log(`This url ${url} exists for illustration purposes only!`);
};

答案 1 :(得分:0)

您可以提供Map的Mock实现,用于跟踪和侦察创建的Map对象。这将允许您在单元测试结束时检查创建了哪些地图以及在它们上调用了什么。