如何使用sinon测试异步方法

时间:2020-11-05 21:02:38

标签: javascript unit-testing mocha sinon sinon-chai

我正在对一个函数进行单元测试,该函数在不等待的情况下调用了另一个异步任务。这样做的原因是因为我不想等待该函数执行。

const fn1 = async () => {
  fn2();
  return 'foo';
};

const fn2 = async () => {
  await fn3();
  await fn4();
};

const fn3 = async () => {
  await s3.upload(params).promise();
};

const fn4 = async () => {
  await s3.upload(params).promise();
};

我想对fn1()和fn2()进行单元测试是一个异步任务,这是我尝试过的事情:

describe("unit test fn1", () => {
  
  let s3Stub;
   
  beforeEach(() => {
     s3Stub = sinon.stub(S3, "upload");
 });

  afterEach(() => {
    s3Stub.restore();
 });
  
  it("fn1 test" , async () => {
     const actualValue = await fn1();
     expect(s3Stub.calledTwice).to.be.true; 
  });

});

理想情况下,s3Stub应该被调用两次,但是只能被调用一次并且我的测试完成。

我不想在fn2()上使用await,因为我希望fn2()作为独立线程运行。关于如何对此类案例进行单元测试的任何想法?

1 个答案:

答案 0 :(得分:1)

用于测试Table* createTable(int size, int dType, int listLength){ // creating the table Table* table = malloc(sizeof(*table)); table->arr=(Object **)malloc(size * sizeof(Object*)); table->arr[1]->data=1; for(int i=0; i<size;i++){ for(int j=0;j<listLength;j++){ Object* node1 =malloc(sizeof(*node1)); Object* node2; if(table->arr[i]==NULL){ table->arr[i]=node1; node1->next=NULL; } else if(node1!=NULL){ node2=table->arr[i]; for(int z=0;node2->next!=NULL;z++){ node2=node2->next; } node2->next=node1; } } } fn1的单元测试解决方案:

fn2

index.js

const s3 = require('./s3'); const fn1 = async () => { exports.fn2(); return 'foo'; }; const fn2 = async () => { await exports.fn3(); await exports.fn4(); }; const fn3 = async () => { await s3.upload(params).promise(); }; const fn4 = async () => { await s3.upload(params).promise(); }; exports.fn1 = fn1; exports.fn2 = fn2; exports.fn3 = fn3; exports.fn4 = fn4;

s3.js

const s3 = { upload() { return this; }, async promise() {}, }; module.exports = s3;

index.test.js

单元测试结果:

const fns = require('./');
const sinon = require('sinon');
const { expect } = require('chai');

describe('64705245', () => {
  afterEach(() => {
    sinon.restore();
  });
  describe('fn1', () => {
    it('should return foo', async () => {
      const fn2Stub = sinon.stub(fns, 'fn2').resolves();
      const actual = await fns.fn1();
      expect(actual).to.be.equal('foo');
      sinon.assert.calledOnce(fn2Stub);
    });
  });

  describe('fn2', () => {
    it('should pass', async () => {
      const fn3Stub = sinon.stub(fns, 'fn3').resolves();
      const fn4Stub = sinon.stub(fns, 'fn4').resolves();
      await fns.fn2();
      sinon.assert.calledOnce(fn3Stub);
      sinon.assert.calledOnce(fn4Stub);
    });
  });
});
相关问题