如何在 Node.js 中模拟 elasticsearch 实例?
How to mock an instance of elasticsearch in Node.js?
我正在使用 elasticsearch 并想为以下代码编写单元测试:
import * as elasticsearch from "elasticsearch";
import config from "../config";
const client = new elasticsearch.Client({
host: config.elasticsearch.host,
log: "trace"
});
export function index(data) {
return new Promise((resolve, reject) => {
client.create({
index: "myindex",
type: "mytype",
id: booking.urn,
body: data
}).then(resolve, reject);
});
}
我熟悉 mocha 和 sinon,但是我不知道在这种情况下 stub\mock client.create
使用什么好的模式。
任何人都可以建议我可以使用的方法吗?
一个可能的选择是使用 proxyquire
+ sinon
组合
诗乃会假Client
:
const FakeClient = sinon.stub();
FakeClient.prototype.create = sinon.stub().returns("your data");
var fakeClient = new FakeClient();
console.log(fakeClient.create()); // -> "your data"
这样的假客户端可以通过 proxyquire
:
注入被测试模块
import proxyquire from 'proxyquire';
const index = proxyquire('./your/index/module', {
'elasticsearch': { Client: FakeClient }
});
如果您尝试代理不包装 elasticsearch 客户端的模块,luboskrnac 的答案将起作用,否则您需要代理嵌套的 elasticsearch 客户端。
// controller.spec.js
const FakeClient = {};
FakeClient.search = () => {};
sinon.stub(FakeClient, 'search').callsFake((params, cb) => cb(null, {
hits: {
hits: [{
_source: {
id: '95254ea9-a0bd-4c26-b5e2-3e9ef819571d',
},
}],
},
}));
controller = proxyquire('./controller', {
'../components/es.wrapper': FakeClient,
'@global': true,
});
包装器
// components/es.wrapper.js
const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({
host: process.env.ELASTICSEARCH_HOST,
});
const wrapper = (method, params, callback) => {
if (process.env.NODE_ENV === 'development') {
params.index = `dev_${params.index}`;
}
return client[method](params, callback);
};
// Wrap ES client methods with dev env prefix
module.exports = {
search: (params, callback) => {
return wrapper('search', params, callback);
},
}
控制器
// controller.js
const es = require('../components/es.wrapper');
module.exports = {
search: (req, res, next) => {
....
es.search(...)
....
}
}
我成功地使用了 https://www.npmjs.com/package/nock ,在端口 9200 模拟了对 elasticsearch 主机的调用。
我正在使用 elasticsearch 并想为以下代码编写单元测试:
import * as elasticsearch from "elasticsearch";
import config from "../config";
const client = new elasticsearch.Client({
host: config.elasticsearch.host,
log: "trace"
});
export function index(data) {
return new Promise((resolve, reject) => {
client.create({
index: "myindex",
type: "mytype",
id: booking.urn,
body: data
}).then(resolve, reject);
});
}
我熟悉 mocha 和 sinon,但是我不知道在这种情况下 stub\mock client.create
使用什么好的模式。
任何人都可以建议我可以使用的方法吗?
一个可能的选择是使用 proxyquire
+ sinon
组合
诗乃会假Client
:
const FakeClient = sinon.stub();
FakeClient.prototype.create = sinon.stub().returns("your data");
var fakeClient = new FakeClient();
console.log(fakeClient.create()); // -> "your data"
这样的假客户端可以通过 proxyquire
:
import proxyquire from 'proxyquire';
const index = proxyquire('./your/index/module', {
'elasticsearch': { Client: FakeClient }
});
如果您尝试代理不包装 elasticsearch 客户端的模块,luboskrnac 的答案将起作用,否则您需要代理嵌套的 elasticsearch 客户端。
// controller.spec.js
const FakeClient = {};
FakeClient.search = () => {};
sinon.stub(FakeClient, 'search').callsFake((params, cb) => cb(null, {
hits: {
hits: [{
_source: {
id: '95254ea9-a0bd-4c26-b5e2-3e9ef819571d',
},
}],
},
}));
controller = proxyquire('./controller', {
'../components/es.wrapper': FakeClient,
'@global': true,
});
包装器
// components/es.wrapper.js
const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({
host: process.env.ELASTICSEARCH_HOST,
});
const wrapper = (method, params, callback) => {
if (process.env.NODE_ENV === 'development') {
params.index = `dev_${params.index}`;
}
return client[method](params, callback);
};
// Wrap ES client methods with dev env prefix
module.exports = {
search: (params, callback) => {
return wrapper('search', params, callback);
},
}
控制器
// controller.js
const es = require('../components/es.wrapper');
module.exports = {
search: (req, res, next) => {
....
es.search(...)
....
}
}
我成功地使用了 https://www.npmjs.com/package/nock ,在端口 9200 模拟了对 elasticsearch 主机的调用。