I would like to add a call to a sync function to the test below:
describe('the server', function() {
it('should respond to a udp packet', function(done) {
// TODO: call async function here
const udp = dgram.createSocket('udp4');
udp.on('error', function(error) {
console.log(error);
});
udp.on('message', function(msg, rinfo) {
console.log('msg', msg);
console.log('rinfo', rinfo);
// TODO: check the reply
udp.close();
done();
});
udp.bind();
// send a request
const bytes = Buffer.from("421a0800117860bc457f0100001a0653455256455222054d54303031", 'hex');
udp.send(bytes, SERVER_PORT, SERVER_ADDR)
});
});
If I just add async
, to make:
it('should respond to a udp packet', async function(done) {
I get an error:
1) the server
should respond to a udp packet:
Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
but I need the done
as the test is only over when a packet is received from the server.
Is there a way of only "returning" from an async function from within an inner function?
CodePudding user response:
There are at least two approaches here: work with the promise returned by the async call or make the whole test function async. I'm going to show the second method becuase it's easier to implement without knowing how the async function call in the todo looks like.
There are basically three changes to be done:
- Make the test function async and remove the
done
parameter. - Wrap the statement or group of statements that use the
done
callback in a promise. Name the first parameter of the promise callbackdone
if you want to keep that name. - return the promise.
describe('the server', function() {
it('should respond to a udp packet', async function() {
// TODO: call async function here
const udp = dgram.createSocket('udp4');
udp.on('error', function(error) {
console.log(error);
});
const promise = new Promise(done => {
udp.on('message', function(msg, rinfo) {
console.log('msg', msg);
console.log('rinfo', rinfo);
// TODO: check the reply
udp.close();
done();
});
});
udp.bind();
// send a request
const bytes = Buffer.from("421a0800117860bc457f0100001a0653455256455222054d54303031", 'hex');
udp.send(bytes, SERVER_PORT, SERVER_ADDR);
return promise;
});
});
This should be sufficient for a test. For a more accurate error handling you may want to reject the promise in case of an exception:
const promise = new Promise((done, reject) => {
try {
udp.on('message', function(msg, rinfo) {
console.log('msg', msg);
console.log('rinfo', rinfo);
// TODO: check the reply
udp.close();
} catch (err) {
reject(err);
return;
}
done();
});
});