I am using elasticsearch and would like to write a unit test for the following code:
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);
});
}
I am familiar with mocha and sinon, however I don't know of a good pattern to use to stub\mock client.create
in this case.
Can anyone suggest an approach that I could use?
The best way to mock Elasticsearch with the official clients is to replace the Connection component since it has very few responsibilities and it does not interact with other internal components other than getting requests and returning responses.
In Jest, Node. js modules are automatically mocked in your tests when you place the mock files in a __mocks__ folder that's next to the node_modules folder. For example, if you a file called __mock__/fs. js , then every time the fs module is called in your test, Jest will automatically use the mocks.
Elasticsearch lets you search through vast amounts of data, whether you're implementing real-time search experiences or doing in-depth data analysis. In this tutorial, you'll learn how to integrate Elasticsearch into your Node. js app.
Once you have Elasticsearch installed and running on your local machine, you can test to see that it's up and running with a tool like curl. By default, Elasticsearch will be running on port 9200. Typically the machine will have a name like localhost .
One possible option is to use proxyquire
+ sinon
combo
Sinon will fake Client
:
const FakeClient = sinon.stub();
FakeClient.prototype.create = sinon.stub().returns("your data");
var fakeClient = new FakeClient();
console.log(fakeClient.create()); // -> "your data"
Such fake client can be passed into module under test by injection via proxyquire
:
import proxyquire from 'proxyquire';
const index = proxyquire('./your/index/module', {
'elasticsearch': { Client: FakeClient }
});
The answer of luboskrnac will works if you are trying to proxiquire module that doesn't wrap elasticsearch client, otherwise you need to proxiquire nested elasticsearch client.
// 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,
});
wrapper
// 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
// controller.js
const es = require('../components/es.wrapper');
module.exports = {
search: (req, res, next) => {
....
es.search(...)
....
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With