8

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?

1

3 Answers 3

9

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 }
});
Sign up to request clarification or add additional context in comments.

Comments

1

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(...)
         ....
    }
}

Comments

0

I had success using https://www.npmjs.com/package/nock , mocking the calls to the elasticsearch host at port 9200.

1 Comment

Can you share a working example? I'm trying nock("https://xxx-yyy-zzz.us-east-2.es.amazonaws.com:9200").post("/*") and getting an SSL error. Not sure the best way to debug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.