Node.js 如何使用sinon模拟postgreSql中池的连接、查询和释放方法?

Node.js 如何使用sinon模拟postgreSql中池的连接、查询和释放方法?,node.js,unit-testing,mocking,mocha.js,sinon,Node.js,Unit Testing,Mocking,Mocha.js,Sinon,我有一个函数,在这里我做一些db操作。像 const { Pool } = require("pg"); const pool = new Pool({ connectionString: `some connection string...`, }); var fun = async function (pk_name, pk_value) { try { const db = await pool.connect(); const query

我有一个函数,在这里我做一些db操作。像

const { Pool } = require("pg");

const pool = new Pool({
  connectionString: `some connection string...`,
});

var fun = async function (pk_name, pk_value) {
  try {
    const db = await pool.connect();
    const query = `SELECT *
                   FROM creds
                   WHERE ${pk_name} = $1`;
    var res = await db.query(query, [pk_value]);
    db.release();
    return res.rows;
  } catch (ex) {
    return [];
  }
};

module.exports.isValidUser = async function (pk_name, pk_value, password) {
  try {
    var userData = await fun(pk_name, pk_value);
    return userData[0].email === pk_value && userData[0].password === password;
  } catch (ex) {
    return false;
  }
};
我试图模拟上述方法,如
pool.connect()
db.query()
db.release()

所以,我试着做以下事情

var sinon = require("sinon");
var assert = sinon.assert;
const { Pool } = require("pg");
const pool = new Pool()
var databaseControllerTestPositive = function () {
  it("valid user check test", async function () {
    sinon.stub(logUtils, "info");
    sinon.stub(pool, 'connect')
    sinon.stub(pool, 'query').returns({
      email: "demo@gmail.com",
      password: "demo"
    })
     sinon.stub(pool.prototype.connect, "release");
    // isValidUser is another function which calls the above fun() internally.
    var result = await dbUtils.isValidUser(  
      "fake_pk_name",
      "fake_pk_value",
      "pass"
    );
    assert.match(result, { rows: [] });
  });
};
但是,上面的测试失败了,我试图模仿的方法并没有真正被模仿

我找到了一个类似的答案,但我没有发现它的答案如此有用

如果我做错了什么,有人能帮我吗。

你可以用,所以我们需要一个额外的包-。由于未导出
fun
函数,因此我们无法要求它并直接测试它。我们需要与
isValidUser
函数一起测试它

例如

main.js

const{Pool}=require('pg');
常量池=新池({
connectionString:`some connection string…`,
});
var fun=异步函数(pk\u名称、pk\u值){
试一试{
const db=wait pool.connect();
const query=`SELECT*
信条
其中${pk_name}=$1`;
var res=await db.query(查询[pk_值]);
db.release();
返回res.rows;
}捕获(ex){
返回[];
}
};
module.exports.isValidUser=异步函数(主键名称、主键值、密码){
试一试{
var userData=wait fun(主键名称、主键值);
返回用户数据[0]。电子邮件===pk\U值和用户数据[0]。密码===password;
}捕获(ex){
返回false;
}
};
main.test.js

const proxyquire=require('proxyquire');
const sinon=要求(“sinon”);
var assert=sinon.assert;
描述('65940805',()=>{
它('有效用户检查测试',异步函数(){
const res={rows:[{email:'fake_pk_value',pass:'pass'}]};
常数dbStub={
查询:sinon.stub().resolves(res),
发布:sinon.stub(),
};
常量池状态桶={
connect:sinon.stub()解析(dbStub),
};
const PoolStub=sinon.stub().返回(PoolStatanceStub);
const dbUtils=proxyquire(“./main”{
pg:{
池:池存根,
},
});
var result=await dbUtils.isValidUser('fake_pk_name','fake_pk_value','pass');
assert.match(结果,true);
sinon.assert.calledWithJustice(池存根{
connectionString:`some connection string…`,
});
sinon.assert.calledOnce(poolStanceStub.connect);
sinon.assert.calledWithJustice(dbStub.query,sinon.match.string,['fake_pk_value']);
sinon.assert.calledOnce(dbStub.release);
});
});
单元测试结果:

  65940805
    √ valid user check test (1013ms)


  1 passing (1s)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |   86.67 |      100 |     100 |   86.67 | 
 main.js  |   86.67 |      100 |     100 |   86.67 | 17,26
----------|---------|----------|---------|---------|-------------------
你可以使用,所以我们需要一个额外的包-。由于未导出
fun
函数,因此我们无法要求它并直接测试它。我们需要与
isValidUser
函数一起测试它

例如

main.js

const{Pool}=require('pg');
常量池=新池({
connectionString:`some connection string…`,
});
var fun=异步函数(pk\u名称、pk\u值){
试一试{
const db=wait pool.connect();
const query=`SELECT*
信条
其中${pk_name}=$1`;
var res=await db.query(查询[pk_值]);
db.release();
返回res.rows;
}捕获(ex){
返回[];
}
};
module.exports.isValidUser=异步函数(主键名称、主键值、密码){
试一试{
var userData=wait fun(主键名称、主键值);
返回用户数据[0]。电子邮件===pk\U值和用户数据[0]。密码===password;
}捕获(ex){
返回false;
}
};
main.test.js

const proxyquire=require('proxyquire');
const sinon=要求(“sinon”);
var assert=sinon.assert;
描述('65940805',()=>{
它('有效用户检查测试',异步函数(){
const res={rows:[{email:'fake_pk_value',pass:'pass'}]};
常数dbStub={
查询:sinon.stub().resolves(res),
发布:sinon.stub(),
};
常量池状态桶={
connect:sinon.stub()解析(dbStub),
};
const PoolStub=sinon.stub().返回(PoolStatanceStub);
const dbUtils=proxyquire(“./main”{
pg:{
池:池存根,
},
});
var result=await dbUtils.isValidUser('fake_pk_name','fake_pk_value','pass');
assert.match(结果,true);
sinon.assert.calledWithJustice(池存根{
connectionString:`some connection string…`,
});
sinon.assert.calledOnce(poolStanceStub.connect);
sinon.assert.calledWithJustice(dbStub.query,sinon.match.string,['fake_pk_value']);
sinon.assert.calledOnce(dbStub.release);
});
});
单元测试结果:

  65940805
    √ valid user check test (1013ms)


  1 passing (1s)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |   86.67 |      100 |     100 |   86.67 | 
 main.js  |   86.67 |      100 |     100 |   86.67 | 17,26
----------|---------|----------|---------|---------|-------------------

谢谢你的回答。这就是我想要的。谢谢你的回答。这就是我要找的。