我正试图找出一种在这个模块中模拟redis的方法:
//module.js
const Redis = require('ioredis');
const myFunction = {
exists: (thingToCheck) {
let redis_client = new Redis(
6379,
process.env.REDIS_URL,
{
connectTimeout: 75,
dropBufferSupport: true,
retryStrategy: functionHere
});
redis_client.exists(thingToCheck, function (err, resp) {
// handlings in here
});
}
};
// test-module.js
const LambdaTester = require('lambda-tester');
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const mockRedis = sinon.mock(require('ioredis'));
describe( 'A Redis Connection error', function() {
before(() => {
mockRedis.expects('constructor').returns({
exists: (sha, callback) => {
callback('error!', null);
}
});
});
it( 'It returns a database error', function() {
return LambdaTester(lambdaToTest)
.event(thingToCheck)
.expectError((err) => {
expect(err.message).to.equal('Database error');
});
});
});
我也试过了一些变化,但我有点卡住,因为我基本上需要模拟构造函数而我不确定Sinon是否支持这个?
mockRedis.expects('exists').returns(
(thing, callback) => {
callback('error!', null);
}
);
sinon.stub(mockRedis, 'constructor').callsFake(() => console.log('test!'));
sinon.stub(mockRedis, 'exists').callsFake(() => console.log('test!'));
我不确定在此处尝试了什么,我也尝试使用rewire建议使用here,但使用mockRedis.__set__("exists", myMock);
从不设置私有变量。
我想最终伪造我的错误路径 我很想听听其他人在节点js中测试redis的过程。
答案 0 :(得分:1)
你的问题不在于Sinon是否支持这个或那个,而是缺乏对"类"在Ecmascript中工作,如在测试代码中存在constructor
属性的尝试所示。这将无法工作,因为该属性与任何结果对象的结果无关。它只是对用于创建对象的函数的引用。我已经介绍了a very similar topic on the Sinon tracker你可能有兴趣阅读以获得一些核心JS foo :-)基本上,不可能存根构造函数,但你可能强迫你的代码在其位置使用另一个构造函数通过DI或链接接缝。
事实上,在同一个帖子中有几个答案,你会看到我的一个例子,说明我自己如何设计一个Redis,使用类可以通过支持依赖注入来轻松测试。您可能需要to check it out,因为它或多或少可直接应用于上面的示例模块。
您已尝试开始使用的另一种技术是使用链接接缝(使用rewire
)。 Sinon主页有nice article这样做。 rewire
和proxyquire
都可以在这里完成这项工作:我认为你通过用mock包装require语句来解决这个问题。
即使我在Sinon维护团队工作,我从不使用mock
功能,所以我不能告诉你如何使用它,因为我认为它模糊了测试,但是让基本的链接接缝工作使用rewire
我基本上会删除所有Sinon代码并获得基本情况(删除redis
以获取已创建的存根模块。)
只有这样,根据需要添加Sinon代码。