I need help in stubbing using sinon msk client functions connect() and send() or sendmessage(). Tried multiple ways but it still invokes the actual function. Please help
Here code snippets in the files.
index.js
var KafkaConnection = require('./mskclient');
var kafkaObj = new KafkaConnection(key.User, key.Secret);
var res = await kafkaObj.connectProducer(event.body);
mskclient.js
class KafkaConnection {
constructor(user, secret) {
this.connection = new Kafka({
authenticationTimeout: 5000,
clientId: client_id,
brokers: brokerlist.split(','),
ssl: true,
sasl: {
mechanism: 'scram-sha-512',
username: user,
password: secret,
},
});
this.producer = null;
}
async sendMessage(msgObj) {
console.log('sendMessage');
this.producer = this.producer || this.connection.producer();
await this.producer.connect();
await this.producer.send(msgObj);
}
async disconnect() {
this.producer && (await this.producer.disconnect());
}
async connectProducer(event) {
try {
log.info('Sending Message');
console.log('connectProducer');
await this.sendMessage({
topic: process.env.TOPIC_NAME,
acks: 1,
messages: [
{
key: 'test-key',
value: JSON.stringify(event),
},
],
});
await this.disconnect();
log.info('Successfully sent message');
return 0;
} catch (e) {
log.info('Message not sent to kafka..');
log.error(e);
await this.disconnect();
return 1;
}
}
}
module.exports = KafkaConnection;
so far I tried the following but both of them is getting called kafka actuall function and not stubs
approach #1
const service = require('../index');
const KafkaConnection = require('../mskclient');
var kafkaObj = sinon.createStubInstance(KafkaConnection);
var res1 = service.handler(event).then(function () {
done();
}).catch((error) => {
done();
})
approach #2
const service = require('../index');
const KafkaConnection = require('../mskclient');
//var kafkaObj = sinon.createStubInstance(KafkaConnection);
SMSStub = sinon.stub(KafkaConnection.prototype, 'KafkaConnection').callsFake(() => {
return 1
});
var res1 = service.handler(event).then(function () {
done();
}).catch((error) => {
done();
})
First, service on its own import connection class independently.
const service = require('../index'); // <-- import '../mskclient' and create obj
const KafkaConnection = require('../mskclient');
Even if you swap them
const KafkaConnection = require('../mskclient');
const kafkaObj = sinon.createStubInstance(KafkaConnection);
const service = require('../index'); // <-- it is still importing the original mskclient
From https://sinonjs.org/how-to/stub-dependency/, if you really want to stub the dependencies, you will have to export a mutable object:
// mskclient.js
module.exports = {
KafkaConnection: class KafkaConnection {},
};
// service.js
const mod = require('./mskclient');
module.exports = function run() {
const conn = new mod.KafkaConnection();
conn.doSomething();
}
But if you use jest
, you could
jest.mock('../mskclient');
// or
jest.mock('../mskclient', () => jest.fn(() => ({
connectProducer: jest.fn(),
})));
const service = require('../index'); // <-- import '../mskclient' and create obj
const KafkaConnection = require('../mskclient');
// es6
import service from '../';
import KafkaConnection from '../mskclient';
jest.mock('../mskclient', () => jest.fn(() => ({
connectProducer: jest.fn(),
})));
SEE: https://jestjs.io/docs/next/es6-class-mocks#automatic-mock