我有一些绑定到UDP端口的测试,例如
describe('the server', function() {
it('should respond to a udp packet', function(done) {
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)
});
});
当测试成功完成时,该代码路径可以调用udp.close()
,让mocha退出。
当测试超过mocha的2秒超时时,我看到错误,但mocha没有退出,因为UDP端口仍在侦听。
当mocha的2秒超时触发时,是否有某种形式的回调/事件可以用来关闭正在侦听的UDP套接字?
这可以通过afterEach
挂钩来实现。afterEach
挂钩是在每次测试后执行的函数,无论测试是否通过(但未跳过(。因此,执行清理操作非常有用,比如在这种情况下关闭套接字。
与所有Mocha挂钩一样,afterEach
是在describe
函数调用中定义的,它适用于该范围内的所有测试。如果您只希望钩子只在一个特定的测试之后运行,请将该测试放入一个专用的describe
函数中。
因此,这里要做的更改如下:
- 将
udp
的声明从it
函数移到包含的describe
函数中。这将使udp
可从it
和afterEach
访问 - 添加一个
afterEach
钩子来执行清理操作:udp.close();
。请记住,无论测试是否因任何原因通过,都会运行此程序,因此最好避免对测试进度进行假设。这里:不要假设udp
已经创建 - 删除对
udp.close();
的其他调用,现在不再需要这些调用
describe('the server', function() {
let udp;
afterEach(() => {
if (udp) {
udp.close();
udp = undefined;
}
});
it('should respond to a udp packet', function(done) {
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
done();
});
udp.bind();
// send a request
const bytes = Buffer.from("421a0800117860bc457f0100001a0653455256455222054d54303031", 'hex');
udp.send(bytes, SERVER_PORT, SERVER_ADDR)
});
});
需要注意的一点是,在超时的情况下,测试函数可能会在套接字关闭后继续运行,从而产生各种令人困惑的错误消息:这并不奇怪。
需要注意的另一件有趣的事情是,describe
函数调用中作用域的变量(与it
函数调用中的变量不同(与Mocha运行的寿命相同。出于这个原因,通常的做法是在需要时(在测试中(延迟创建这些变量,并在不再需要时立即通过将其明确设置为undefined
或null
来手动清除。
您还可以使用mocha --exit
,这比自己关闭套接字要简单得多。