vishnu
vishnu

Reputation: 197

How to mock async method with axios.post using sinon?

I am trying to mock an async function which internally calls n async method in another js file. When i mock the the async function, it says 'expected post to be caaled atleast once'. Can someone please help? Thank you very much in advance.

Controller.js

//all imports done here
var producer= require(./Producer)
const result = async function(req,res,"login"){
const link = req.query.param === team ? '/login' : '/search';
await producer.produce(req,res);
const result = await axios.post(link,req.name,req.dob):
await producer.produce(req,res,"logout");
}

Producer.js

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

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

const produce = async function (req,res,data) =>{

  // Create a producer client to send messages to the event hub.
try{
  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");
}catch(error){
throw e;
}
}

controller-test.js

const controller = require(./controller);
describe("execute", =>{
  sinon.stub().restore();
  const req= {name:"tina", dob:"2-12-2000"};
  it("call method to post" =>{
  const res = controller.result();
//test fails in the below line
  sinon.assert(axios.post,"http://dummyurl/login,req);
 });
});

Upvotes: 0

Views: 1952

Answers (1)

Lin Du
Lin Du

Reputation: 102477

You can use sinon.stub(obj, 'method') to stub producer.produce() method and axios.post() method.

Besides, you should use async/await for testing asynchronous code, so that Mocha will know that it should wait for this function to be called to complete the test.

E.g.

Controller.js:

const producer = require('./Producer');
const axios = require('axios');

const result = async function (req, res) {
  const team = 'thunder';
  const link = req.query.param === team ? '/login' : '/search';
  await producer.produce(req, res);
  const result = await axios.post(link, req.name, req.dob);
  await producer.produce(req, res, 'logout');
};

module.exports = { result };

Producer.js

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

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

const produce = async (req, res, data) => {
  try {
    const producer = new EventHubProducerClient(connectionString, eventHubName);
    const batch = await producer.createBatch();
    batch.tryAdd({ body: 'First event' });
    batch.tryAdd({ body: 'Second event' });
    batch.tryAdd({ body: 'Third event' });
    await producer.sendBatch(batch);
    await producer.close();
    console.log('A batch of three events have been sent to the event hub');
  } catch (error) {
    throw e;
  }
};

module.exports = { produce };

Controller.test.js:

const sinon = require('sinon');
const axios = require('axios');
const controller = require('./controller');
const producer = require('./Producer');

describe('execute', () => {
  afterEach(() => {
    sinon.restore();
  });
  it('call method to post', async () => {
    sinon.stub(axios, 'post');
    sinon.stub(producer, 'produce');
    const req = { name: 'tina', dob: '2-12-2000', query: { param: 'thunder' } };
    await controller.result(req, {});
    sinon.assert.calledWithExactly(axios.post, '/login', 'tina', '2-12-2000');
    sinon.assert.calledTwice(producer.produce);
  });
});

Test result:

  execute
    ✓ call method to post


  1 passing (5ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |   58.33 |       50 |      50 |   58.33 |                   
 Producer.js   |   33.33 |      100 |       0 |   33.33 | 7-17              
 controller.js |     100 |       50 |     100 |     100 | 6                 
---------------|---------|----------|---------|---------|-------------------

Upvotes: 2

Related Questions