我无法理解如何使用 sinon 来模拟对 postgres 的调用,这是我正在测试的模块所需要的,或者如果它可能的话。
我并不是要测试 postgres 模块本身,只是我的目标是确保它按预期工作,并且它正在调用它在这种情况下应该调用的内容。
我想问题是需要设置 Node ,因为我的模块需要 postgres 模块来访问数据库,但在这里我不想运行集成测试我只是想确保我的代码正常工作孤立地,并不真正关心数据库在做什么,我会把它留给我的集成测试。
我看到有些人将他们的函数设置为具有可选参数以将 mock/stub/fake 发送到函数,测试它是否存在以及是否在所需模块上使用它,但这看起来像是闻到我的味道(我是 Node 的新手,所以也许这不是)。
如果可能的话,我更愿意模拟它,而不是尝试劫持需求。
一些代码(请注意这不是真正的代码,因为我正在使用 TDD 和 函数实际上什么都不做,函数名是真实的)
测试设置
describe('#execute', function () {
it('should return data rows when executing a select', function(){
//Not sure what to do here
});
});
样本函数
PostgresqlProvider.prototype.execute = function (query, cb) {
var self = this;
if (self.connection === "")
cb(new Error('Connection can not be empty, set Connection using Init function'));
if (query === null)
cb(new Error('Invalid Query Object - Query Object is Null'))
if (!query.buildCommand)
cb(new Error("Invalid Query Object"));
//Valid connection and query
};
像这样环绕 postgres 模块可能看起来有点滑稽,但有一些设计,因为这个应用程序将有几个“提供者”,我想为它们公开相同的 API,以便我可以互换使用它们。
更新
我认为我的测试太复杂了,因为我想看看是否已经进行了连接调用,然后返回数据,这让我闻起来很臭,所以我把它剥离并放入两个测试中:
模拟测试
it('should call pg.connect when a valid Query object is parsed', function(){
var mockPg = sinon.mock(pg);
mockPg.expects('connect').once;
Provider.init('ConnectionString');
Provider.execute(stubQueryWithBuildFunc, null, mockPg);
mockPg.verify();
});
这有效(我认为)因为没有 postgres 连接器代码它失败了,它通过了(Boom :))
现在的问题是第二种方法,我将使用一个 stub (可能是 spy ),当它应该失败时它会通过 100%,所以我会在早上拿起它。
更新 2
我对测试不是 100% 满意,主要是因为我没有劫持访问数据库的 client.query 方法,而只是劫持我的执行方法并强制它沿着一条路径前进,但它允许我查看结果并对其进行断言以测试行为,但愿意接受任何建议的改进。
我正在使用 spy 来捕获该方法并返回 null 和一个包含行的人造对象,就像该方法会传回一样,此测试将随着我添加更多查询行为而改变,但它让我克服了障碍。
it('should return data rows when a valid Query object is parsed', function(){
var fauxRows = [
{'id': 1000, 'name':'Some Company A'},
{'id': 1001, 'name':'Some Company B'}
];
var stubPg = sinon.stub(Provider, 'execute').callsArgWith(1, null, fauxRows);
Provider.init('ConnectionString');
Provider.execute(stubQueryWithBuildFunc, function(err, rows){
rows.should.have.length(2);
}, stubPg);
stubPg.called.should.equal.true;
stubPg.restore();
});
最佳答案
使用 pg 池:https://www.npmjs.com/package/pg-pool
无论如何它都将被添加到 pg 中,据称可以使(模拟)单元测试更容易......来自 BrianC(https://github.com/brianc/node-postgres/issues/1056#issuecomment-227325045):
Checkout https://github.com/brianc/node-pg-pool - it's going to be the pool implementation in node-postgres very soon and doesn't rely on singletons which makes mocking much easier. Hopefully that helps!
关于javascript - 在 Node.js 中使用 Sinon.js 模拟 Postgres 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13102693/