在节点中模拟postgres调用

我有一个类似的代码

const pg = require('pg'); const async = require('async'); const conn = 'pg://username:pass@my_db:2435/db'; const client = new pg.Client(conn); exports.handler = function(event, context) { async.waterfall([ query_aggregate(callback), my_next_function(rows, callback) ], function (err) { if (err) { context.fail(err); } else { context.succeed('Succeed'); } }); }; function query_aggregate(callback) { client.connect(function (err) { if(err) callback(err); const query = 'SELECT shop_id, COUNT(DISTINCT(user_id)) from connections GROUP BY sshop_id'; client.query(query, function (err, result) { if (err) callback(err); client.end(function (err) { if (err) callback('Error in query:', err); callback(null, result.rows); }); }); }); } if (typeof exports !== 'undefined') { exports.query_aggregate = query_aggregate; } 

但在testing中,我想validation发生了什么,当我有错误,也正确地返回一个callbackrows 。 但如何嘲笑client.connectclient.query

就目前而言,我只是尝试用https://stackoverflow.com/a/10124424/2747638与sinon的答案:

 const testingAggregate = require('../index.js'); const assert = require('assert'); const expect = require('chai').expect; const sinon = require('sinon'); describe('Testing aggregate function', function () { describe('query_aggregate', function() { it('fail to connect to postgres', function(done){ let mock; mock = sinon.mock(require('pg')); mock.expect('connect').once(); testingAggregate.query_aggregate(function(err, data){ expect(err).to.equal('Failed to connect to postgres'); done(); }); mock.verify(); }); }); }); 

  1) Testing aggregate function query_aggregate fail to connect to postgres: TypeError: mock.expect is not a function 

我看到一个提到pg-pool的github问题,但没有任何具体的例子。

编辑1:

我有这个简单的摩卡testing:使用proxyquire但它失败。

  describe('query_aggregate', function() { it('fail to connect to postgres', function(done){ proxyquire('../index', { Cient: function(host) { console.log(host); // print pg://host:3456 this.connect = function(callback) { console.log('Here!'); // never printed callback(new Error('Failed to connect to postgres')) } } } }); testingAggregate.query_aggregate(function(err, data){ expect(err).to.equal('Failed to connect to postgres'); done(); }); }); }); 

testing结果 :

  1) Testing aggregate function query_aggregate fail to connect to postgres: Uncaught AssertionError: expected [Error: connect EHOSTDOWN 168.410.131.63:3456 - Local (0.0.0.0:0)] to equal 'Failed to connect to postgres' 

你有什么想法,为什么我不能模拟connect

在此先感谢您的帮助。

我终于使用了proxyquire。 这个答案可能不是最好的。

为了testing函数query_aggregate我做了:

 const proxyquire = require('proxyquire').noCallThru(); const assert = require('assert'); const expect = require('chai').expect; describe('Testing aggregate function', function () { describe('query_aggregate', function() { it('fail to connect to postgres', function(done){ let pgStub = { Client: function(host) { this.connect = function(callback) { callback(new Error('Failed to connect to postgres')); }; } }; let testingAggregate = proxyquire('../index', { 'pg': pgStub }); testingAggregate.query_aggregate(function(err, data){ expect(err).to.deep.equal(new Error('Error: Failed to connect to postgres')); done(); }); }); it('fail on query and return an error', function(done){ let pgStub = { Client: function(host) { this.connect = function(callback) { callback(); }; this.query = function(query, callback) { callback(new Error('Failed to query postgres')); }; } }; let testingAggregate = proxyquire('../index', { 'pg': pgStub }); testingAggregate.query_aggregate(function(err, data){ expect(err).to.deep.equal(new Error('Error: Failed to connect to postgres')); done(); }); }); it('succeed on query and return rows', function(done){ let resultRows = [{ a:1 },{ b:2 }]; let pgData = { rows: resultRows }; let pgStub = { Client: function(host) { this.connect = function(callback) { callback(); }; this.query = function(query, callback) { expect(query).to.eq('SELECT shop_id, COUNT(DISTINCT(user_id)) from connections GROUP BY shop_id'); callback(null, pgData); }; } }; let testingAggregate = proxyquire('../index', { 'pg': pgStub }); testingAggregate.query_aggregate(function(err, data){ expect(data).to.deep.equal(resultRows); done(); }); }); }); });