我正在尝试通过在我的 mocha 测试文件中打开 websocket 客户端、连接到 ws 服务器并等待响应来测试我的 websocket 服务器。我向 ws 服务器发送一个 http 请求,然后通过 websocket 向客户端发送一条消息,我在其中存储结果并对其进行测试。
我得到了我想要的响应并且测试通过了,但是 mocha 测试本身并没有终止,我不得不手动关闭它。
我已经读过这个- 解释可能仍然有一些异步进程打开,例如打开的套接字,但我尝试终止套接字,并且我得到了“关闭”事件触发(我得到了我定义的控制台日志消息'close' 事件监听器),但测试仍未结束。
我正在使用 ws (npm)、mocha、chai(用于断言)和 supertest(调用服务器以发送响应)。
版本:
"ws": "^7.3.0",
"摩卡": "^7.0.0",
"柴": "^4.2.0",
"超测": "^4.0.2",
节点:v12.9.1
我知道我可以使用 --exit 标志,正如这个堆栈溢出答案中所建议的那样,但如果可以避免的话,我不希望这样做。
以下是相关代码:
'use strict';
const supertest = require('supertest');
const assert = require('chai').assert;
const paths = require('../common/paths');
const { sign } = require('../common/signing');
const WebSocket = require('ws');
describe.only('Events server tests', function () {
this.timeout(11000);
const docId = 'doc_events_' + Date.now();
const wsServerUrl = 'ws://localhost:8080/subscribe?params={"prefix_doc_id":"doc_events_"}';
const ws = new WebSocket(wsServerUrl);
let id_from_msg;
// Connection opened
ws.addEventListener('open', function (event) {
console.log('connection started!');
});
// Listen for messages
ws.addEventListener('message', function (event) {
console.log('\n\nMessage from server ', event.data, ' ', typeof event.data);
try {
// the msg recived via websocket is in the form of: "doc_id":X, and I store the docID in order to check if it matches the docId that was sent in the test.
if (event.data.includes('doc_id')) {
id_from_msg = JSON.parse(event.data).doc_id;
}
} catch (error) {
console.log('error: ', error);
}
});
ws.addEventListener('close', () => {
console.log('closed connection!');
});
before((done) => {
console.log('start');
done();
});
after((done) => {
ws.terminate();
// ws.close();
done();
console.log('after?');
});
it('Test 1 - send simple request to events server', (done) => {
const eventsUrl = paths.EVENTS.EVENTS();
const eventsObj = {
reqId: '',
docId: docId,
sessionId: 1,
status: 200
};
// This tests is used to invoke response from the socket server, and it works fine, the tests passes and ends without an issue.
supertest('http://localhost:3035')
.post(eventsUrl)
.set('Authorization', sign('post', eventsUrl, eventsObj))
.send(eventsObj)
.expect(200)
.expect(res => {
assert.ok(res.body);
assert.equal(id_from_msg, docId);
})
.end(done);
});
});
如您所见,我在“after”部分尝试了 ws.close() 和 ws.terminate(),并且都产生了相同的结果:测试没有结束,并且 console.log('after?')在调用 done() 后触发行。
我试图覆盖'onclose'方法并手动触发,但无济于事。
我还尝试在测试本身中关闭 websocket(我的意思是在“it”部分,即使我在语义上不喜欢它) - 但测试套件本身并没有终止,和以前一样。
有没有办法确保在调用 done() 之前正确关闭 websocket?