怎么使用sinon和mocha在MySQL查询节点上模拟Promisify调用?

本教程将介绍如何使用sinon和mocha在MySQL查询节点上模拟Promisify调用?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

怎么使用sinon和mocha在MySQL查询节点上模拟Promisify调用? 教程 第1张

问题描述

这是我使用MySQL的代码-

import * as mysql from 'mysql';
import {promisify} from 'util';


 const connectionParams:any = {
  /* set as environment variables */
  host: host,
  user: user,
  password: password,
  port: parseInt(port)
 };
 var connection:any;
 const getRecords = async (inputValue: string) => {

//validate inputValue

const userIds: string[] = [];
logger.info("Creating mysql connection");
try {
 connection = mysql.createConnection(connectionParams);
 const query = promisify(connection.query).bind(connection);
 const queryResult = await query({ sql: sqlQuery, timeout: 1000, values: value1, inputValue] });
 if (queryResult) {
  queryResult.forEach((row) => {
userIds.push(row.userid);
  });
 }
} catch (error) {
 logger.info(error);
 // console.log(error);
 throw new Error('Could not retrieve user IDs');
} finally {
 connection.end();
}
return userIds;
 };

这是我的测试-

it('should return a list of records when right inputs are given', async() => {
  sinon.stub(process, 'env').value({
'database': 'TESTDB'
  });
  let dummyArray = [{ userid: 'xyz' }];
  let createConnection = {
connect: function(connectionParams: any) {
 return Promise.resolve()
},
query : sinon.stub().withArgs({}).callsFake(function (...args): Promise<Object>{
 const dummyArray = [{ userid: 'xyz' }];
 return new Promise(function(resolve){resolve(dummyArray)});
}),
end: function() {}
  };
  let mySqlStub = {
createConnection: sinon.stub().returns(createConnection)
  };
  const dbops = proxyquire('../../lib/dbops', {'mysql': mySqlStub}).default;
  expect(await dbops.getUserIds('Delete')).to.deep.equal(['xyz']);
 });

怎么编写查询的FAKE函数?

查询:sinon.stub().with Args({}).alls sFake(Function(...args):
承诺{
常量虚拟数组=[{userid:‘XYZ’}];
返回新的Promise(function(resolve){resolve(dummyArray)});
})

这对我不起作用。我怎么才能让它起作用呢?我无法让存根函数在Main函数中解析和返回预期的值。查询只是挂起,并在超时后抛出错误。存根中的&quot;matchingfakes&quot;方法中出现错误。

推荐答案

proxyquire用于截断模块或包的独立函数导出。由于mysql是一个对象,您可以通过sinon.stub(obj, 'method')来存根它的方法。您不需要使用Useproxyquire包。

即使您使用util.promisify为NodeJS错误优先回调方法(mysql.query(sql, callback),回调签名为function (error, results, ...args): void)生成Promise版本。您需要使用.callsFake()为此方法创建模拟实现,并通过调用其回调来触发Promise版本。

并且,您应该在清除环境变量之后import该函数。因为当您导入./dbops模块时,模块作用域中的代码将立即执行,此时,环境变量不会被存根。

例如

dbops.ts

import mysql from 'mysql';
import { promisify } from 'util';

const connectionParams: any = {
  host: process.env.HOST,
  user: process.env.USER,
  password: process.env.PASSWORD,
  port: parseInt(process.env.PORT || '3306'),
};
var connection: any;

const getRecords = async (inputValue: string) => {
  const sqlQuery = 'SELECT * FROM tests';
  const value1 = '';
  const userIds: string[] = [];
  console.info('Creating mysql connection');
  try {
 connection = mysql.createConnection(connectionParams);
 const query = promisify(connection.query).bind(connection);
 const queryResult = await query({ sql: sqlQuery, timeout: 1000, values: value1, inputValue });
 if (queryResult) {
queryResult.forEach((row) => {
  userIds.push(row.userid);
});
 }
  } catch (error) {
 console.info(error);
 throw new Error('Could not retrieve user IDs');
  } finally {
 connection.end();
  }
  return userIds;
};

export { getRecords };

dbops.test.ts

import sinon from 'sinon';
import mysql from 'mysql';

describe('69702002', () => {
  it('should return a list of records when right inputs are given', async () => {
 sinon.stub(process, 'env').value({
HOST: '127.0.0.1',
USER: 'testuser',
PASSWORD: 'testpwd',
PORT: '3306',
 });
 const { getRecords } = await import('./dbops');
 const dummyArray = [{ userid: 'xyz' }];

 let connectionStub = {
query: sinon.stub().callsFake((sql, callback) => {
  callback(null, dummyArray);
}),
end: sinon.stub(),
 };
 sinon.stub(mysql, 'createConnection').returns(connectionStub);
 const actual = await getRecords('test input');
 sinon.assert.match(actual, ['xyz']);
 sinon.assert.calledWithExactly(mysql.createConnection, {
host: '127.0.0.1',
user: 'testuser',
password: 'testpwd',
port: 3306,
 });
 sinon.assert.calledOnce(connectionStub.end);
  });
});

测试结果:

 69702002
Creating mysql connection
 ✓ should return a list of records when right inputs are given (945ms)


  1 passing (952ms)

----------|---------|----------|---------|---------|-------------------
File| % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |90.48 | 50 |  100 |90 | 
 dbops.ts |90.48 | 50 |  100 |90 | 27-28 
----------|---------|----------|---------|---------|-------------------

好了关于怎么使用sinon和mocha在MySQL查询节点上模拟Promisify调用?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。