How do I structure tests for asynchronous functions?

天涯浪子 提交于 2019-12-01 03:26:05

问题


I'm accustomed to writing Mocha tests using the standard NodeJs assert library like this:

describe('Some module', () => {
   var result = someCall();
   it('Should <something>', () => {
      assert.ok(...);
   });
})

but now my call returns a promise... so I want to write:

describe('Some module', async () => {
   var result = await someCall();
   it('Should <something>', () => {
      assert.ok(...);
   });
})

but it doesn't work. My tests don't run at all. Curiously,

describe('Some module', async () => {
   it('Should <something>', () => {
      var result = await someCall();
      assert.ok(...);
   });
})

works fine but the problem is that I want to make a single call and run many tests against it, so I want to make the call outside the it() calls

How do I make it work?

and please don't recommend Chai. I want to use the standard assert library


回答1:


before accepts an async function so you can get the result before your tests run and use it in your tests like this:

const assert = require('assert');

const someCall = () => Promise.resolve('hi');

describe('Some module', () => {
  let result;

  before(async () => {
    result = await someCall();
  });

  it('Should <something>', () => {
    assert.equal(result, 'hi');  // Success!
  });
});



回答2:


Although a little unconventional in use, one approach might be to use the before() hook to achieve what you require.

The before() hook would provide a means of calling functionality (ie someCall()) prior to the rest of the tests in your suite. The hook itself supports execution of asynchronous functionality via a callback function (ie done) that can be called once asynchronous functionality has completed:

before((done) => {
  asyncCall().then(() => {
    /* Signal to the framework that async call has completed */
    done(); 
  });
});

One way to integrate this with your existing code might be as follows:

describe("Some module", () => {
  /* Stores result of async call for subsequent verification in tests */
  var result;

  /* User before hook to run someCall() once for this suite, and
  call done() when async call has completed */
  before((done) => {
    someCall().then((resolvedValue) => {
      result = resolvedValue;
      done();
    });
  });

  it("Should <something>", () => {

    /* result variable now has resolved value ready for verification */
    console.log(result);
  });
});

Hope that helps




回答3:


Mocha already supports what you want to do.

Mocha's describe function is not designed to work asynchronously. However, the it function is designed to work asynchronously either by passing a done callback (the actual parameter name can be anything such as "complete" or "resolve" or "done"), returning a promise or passing an async function.

Which means your test is almost correct. You just need to do this instead:

describe('Some module', () => {
   it('Should <something>', async () => {
      var result = await someCall();
      assert.ok(...);
   });
})

If you need to run the someCall() function once for multiple it blocks you can do as mentioned in the other answers and call it in a before block.



来源:https://stackoverflow.com/questions/55232992/how-do-i-structure-tests-for-asynchronous-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!