如何使用 sinon 使用 axios.post 模拟异步方法?

Posted

技术标签:

【中文标题】如何使用 sinon 使用 axios.post 模拟异步方法?【英文标题】:How to mock async method with axios.post using sinon? 【发布时间】:2022-01-04 19:02:25 【问题描述】:

我正在尝试模拟一个异步函数,该函数在另一个 js 文件中内部调用 n async 方法。当我模拟异步函数时,它说“预计帖子至少会被调用一次”。有人可以帮忙吗?非常感谢您。

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);
 );
);

【问题讨论】:

【参考方案1】:

您可以使用sinon.stub(obj, 'method') 来存根producer.produce() 方法和axios.post() 方法。

此外,您应该使用async/await 来测试异步代码,以便Mocha 知道它应该等待调用此函数来完成测试。

例如

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);
  );
);

测试结果:

  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                 
---------------|---------|----------|---------|---------|-------------------

【讨论】:

以上是关于如何使用 sinon 使用 axios.post 模拟异步方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Typescript 中使用 Sinon?

如何测试 react-saga axios post

如何将简单值从 axios.post 发送到 asp.net 核心?

如何使用 sinon 存根 new Date()?

如何从axios.post发送简单的值到asp.net核心?

React.js - 如何使用 axios POST 方法将数据从 div 传递到函数?