vishnu
vishnu

Reputation: 197

How to mock eventHubclient (azure/event-hub) producer connectivity for unit testing using mocha?

Below is the node js code I want to mock the eventHub connection in order to invoke the API call.


const { EventHubProducerClient } = require("@azure/event-hubs");

const connectionString = "EVENT HUBS NAMESPACE CONNECTION STRING";
const eventHubName = "EVENT HUB NAME";

async function main() {

  // Create a producer client to send messages to the event hub.
  const producer = new EventHubProducerClient(connectionString, eventHubName);

  // Prepare a batch of three events.
  const batch = await producer.createBatch();
  batch.tryAdd({ body: "First event" });
  batch.tryAdd({ body: "Second event" });
  batch.tryAdd({ body: "Third event" });    

  // Send the batch to the event hub.
  await producer.sendBatch(batch);

  // Close the producer client.
  await producer.close();

  console.log("A batch of three events have been sent to the event hub");
}

main().catch((err) => {
  console.log("Error occurred: ", err);
});

please help thanks in advance.

Upvotes: 0

Views: 2070

Answers (1)

Lin Du
Lin Du

Reputation: 102527

I will use sinon as stub library. It is often used with mocha. From the doc How to stub a dependency of a module:

Sinon is a stubbing library, not a module interception library. Stubbing dependencies are highly dependant on your environment and the implementation. For Node environments, we usually recommend solutions targetting link seams or explicit dependency injection. Though in some more basic cases, you can get away with only using Sinon by modifying the module exports of the dependency.

To stub a dependency (imported module) of a module under test you have to import it explicitly in your test and stub the desired method. For the stubbing to work, the stubbed method cannot be destructured, neither in the module under test nor in the test.

Since the dependency of the code under test is a class imported from the package instead of using dependency injection. I am going to use link seams to stub the @azure/event-hubs module and EventHubProducerClient class.

E.g.

main.js:

const { EventHubProducerClient } = require('@azure/event-hubs');

const connectionString = 'EVENT HUBS NAMESPACE CONNECTION STRING';
const eventHubName = 'EVENT HUB NAME';

async function main() {
  // Create a producer client to send messages to the event hub.
  const producer = new EventHubProducerClient(connectionString, eventHubName);

  // Prepare a batch of three events.
  const batch = await producer.createBatch();
  batch.tryAdd({ body: 'First event' });
  batch.tryAdd({ body: 'Second event' });
  batch.tryAdd({ body: 'Third event' });

  // Send the batch to the event hub.
  await producer.sendBatch(batch);

  // Close the producer client.
  await producer.close();

  console.log('A batch of three events have been sent to the event hub');
}

module.exports = main;

main.test.js:

const proxyquire = require('proxyquire');
const sinon = require('sinon');

describe('68808576', () => {
  it('should pass', async () => {
    const batchStub = {
      tryAdd: sinon.stub(),
    };
    const producerStub = {
      createBatch: sinon.stub().resolves(batchStub),
      sendBatch: sinon.stub(),
      close: sinon.stub(),
    };
    const EventHubProducerClientStub = sinon.stub().returns(producerStub);
    const main = proxyquire('./main', {
      '@azure/event-hubs': { EventHubProducerClient: EventHubProducerClientStub },
    });
    await main();
    sinon.assert.calledWithExactly(
      EventHubProducerClientStub,
      'EVENT HUBS NAMESPACE CONNECTION STRING',
      'EVENT HUB NAME',
    );
    sinon.assert.calledOnce(producerStub.createBatch);
    sinon.assert.calledThrice(batchStub.tryAdd);
    sinon.assert.calledWithExactly(producerStub.sendBatch, batchStub);
    sinon.assert.calledOnce(producerStub.close);
  });
});

test result:

  68808576
A batch of three events have been sent to the event hub
    ✓ should pass (1946ms)


  1 passing (2s)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 main.js  |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

Upvotes: 1

Related Questions