首页 > 解决方案 > 用于实例化单个对象的模式,同时保持可测试性

问题描述

当我的应用程序启动时,它会实例化 Redis 客户端对象:

const redisClient = redis.createClient(REDIS_URL);

我维护了一个代理对象myRedisClient,它公开了客户端对象公开的 API 的承诺版本:

const get = (key) => 
    new Promise((resolve, reject) =>
        redisClient.get(key, (err, resp) => 
            err ? reject(err) : resolve(resp))

const myRedisClient = { get };

简单地隐式实例化感觉是错误的redisClient,所以我想把它放在一个显式调用的方法中:

let redisClient = null;
const init = () => redisClient || redis.createClient(REDIS_URL);
const myRedisClient = { init, get};

get需要访问redisClient. 如果与变量get在同一个文件中,那么这很简单。redisClient

但是,如果get在单独的文件中,redisClient可以通过关闭它并将redisClient其作为参数添加到get.

// my-redis-client.js
import get from './get';

let redisClient = null;
const init = () => redisClient || redis.createClient(REDIS_URL);
const myRedisClient = { init, get(key) => get(redisClient, key) };

// get.js
const get = (redisClient, key) => 
    new Promise((resolve, reject) =>
        redisClient.get(key, (err, resp) => 
            err ? reject(err) : resolve(resp));

最后,我希望能够 stub out redisClient,并且我想我可以redis.createClient在从测试中调用它之前进行 stub out (例如,使用内置于测试运行器中的 stubbing 功能)。

这个过程听起来是否合理?

标签: javascript

解决方案



推荐阅读