使用sinon mocks设置摩卡测试,并带有mysql和bluebird承诺
Set up a mocha tests with sinon mocks, with mysql and bluebird promises
我给她准备了一个具有以下设置的项目:JavaScript ES6(用Babel转译),mocha测试,使用node-mysql和Bluebird Promises访问MySql。
也许将 Bluebird 与 Babel/ES6 一起使用已经是我的第一个问题,但让我们解释一下情况和问题:
我的数据库虚拟对象:
let XDate = require('xdate'),
_ = require('lodash');
const Promise = require("bluebird");
const debug = require('debug')('DBRepository');
class DBRepository {
constructor(mysqlMock) {
"use strict";
this.mysql = mysqlMock;
if( this.mysql == undefined) {
debug('init mysql');
this.mysql = require("mysql");
Promise.promisifyAll(this.mysql);
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
}
this.config = {
connectionLimit: 10,
driver: 'pdo_mysql',
host: 'my_sql_container',
port: 3306,
user: 'root',
password: '**********',
testDbName: 'db-name'
};
this.pool = this.mysql.createPool(this.config); // <== Here the error is thrown
}
getSqlConnection() {
return this.pool.getConnectionAsync().disposer(function (connection) {
try {
connection.release();
} catch (e) {
debug('Error on releasing MySQL connection: ' + e);
debug(e.stack);
}
});
}
getGoods(queryParams) {
"use strict";
if (queryParams === undefined) {
queryParams = {};
}
if (queryParams.rowCount === undefined) {
queryParams.rowCount = 15;
}
let query = "SELECT id, name FROM my_table";
return Promise.using(this.getSqlConnection(), (conn => {
debug('query: ' + query);
return conn.queryAsync(query);
}));
}
}
这段代码在我的普通代码中对我来说效果很好,但是当我尝试在摩卡测试中使用 int 时,使用 sinon 进行模拟,我得到以下错误TypeError: this.mysql.createPool is not a function
这是我的测试代码:
let expect = require('chai').expect,
XDate = require('xdate'),
_ = require('lodash'),
sinon = require('sinon'),
Promise = require('bluebird'),
toBeMocketMySql = require('mysql');
Promise.promisifyAll(toBeMocketMySql);
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
describe(".inflateOffers(offerPCs, offerGroups)", () => {
"use strict";
it('should inflate Offers (with all OfferGroups and a PricingCluster from db rows.', () => {
let offerPCs = JSON.parse('[... some objects ...]');
let offerGroups = JSON.parse('[... some objects ...]');
let mock = sinon.mock(toBeMocketMySql);
let dbRepo = new DBRepository(mock); // <== Here the error is thrown
let offers = dbRepo.inflateObjects(offerPCs, offerGroups);
expect(offers).to.be.an('object')
.and.to.be.an('array')
.to.have.length(1);
expect(offers[0]).to.be.an('object')
.and.not.to.be.an('array')
.to.have.property('a')
.to.have.property('b');
});
});
也许根本不可能嘲笑一个被捧头的对象?
有人在这方面有经验吗?
DBRepository
很难测试,因为事情太多了 - 为了使测试更容易,你需要分离一些关注点。至少你需要将你的业务逻辑(原始SQL查询)分解成它们自己的类,如下所示:
class GoodsService {
/**
* Constructor - inject the database connection into the service.
*
* @param {object} db - A db connection
*/
constructor(db) {
this.db = db;
}
getGoods(queryParams) {
if (queryParams === undefined) {
queryParams = {};
}
if (queryParams.rowCount === undefined) {
queryParams.rowCount = 15;
}
let query = "SELECT id, name FROM my_table";
debug('query: ' + query);
return this.db.queryAsync(query);
}
}
因此,现在您已将业务逻辑与设置数据库连接器分开。您可以只将完全实例化的数据库连接或存根传递到服务类测试中,如下所示:
let assert = require('assert');
describe('GoodsService', () => {
it('should return an array', () => {
let stubbedDb = {
queryAsync: () => {
return Promise.resolve([]);
}
};
let instance = new GoodsService(stubbedDb);
return instance.getGoods()
.then((result) => {
assert(Array.isArray(result), 'should return an array of something');
});
});
});
这有点过于简单,但你应该明白这个想法。但是,有一些事情需要注意。
你不需要像柴这样的花哨的东西来测试承诺。摩卡已经对此有很好的内置支持。
你不需要像sinon.mock
那样使用魔法.相反,保持简单,只是"存根"您需要在依赖项中测试的方法。但是,您可以使用"间谍"来检查正在生成正确的 SQL,但我会在集成测试中这样做。
这有帮助吗?
相关文章:
- 我的职位回报太快了,如何做出承诺
- 打破承诺链的好方法是什么
- 使用jquery将mysql数据获取到新的表行中
- 从函数返回角度承诺
- 我怎样才能获得承诺的价值
- 延期承诺值未更新/解析/延期
- 将地理编码结果转换为php变量以发布到mysql数据库
- 在承诺链中处理早期回报的最佳方式
- 承诺在非节点式回调上使用Bluebird
- 如何使用JS禁用表行,并在MYSQL中插入所选选项
- 从MySQL数据库中获取输入数据需要两次页面刷新
- 将一个表的id与另一个表中的user_id进行匹配,以获取mysql中的记录
- 简单的ES6承诺问题-交换解决和拒绝参数
- 组合承诺和非承诺值
- 带有对象/原型的链式承诺(Q延期)
- AngularJS$q承诺使用socket.io
- 在php和mysql中选择选项.一旦选择了选项,就列出我的sql数据库数据
- 使用sinon mocks设置摩卡测试,并带有mysql和bluebird承诺
- 承诺的mysql模块如何与NodeJS一起工作
- 使用承诺api与Node Mysql不工作