Websocket server doesn't seem to be connecting
See original GitHub issueI’ve got a project where a node micro service is connected to a rails actioncable websocket.
I’m trying to speck the websocket connection part (regardless of the fact it’s an actioncable websocket behind the scenes) by using jest
and jest-websocket-mock
and mock-socket
.
My ActionCable
class connection method looks like this
// lib/classes/action_cable.js
const WebSocket = require('ws');
class ActionCable {
constructor(url, opts) {
this.cableURL = url;
this.origin = opts.origin || 'http://localhost:3000';
this.headers = opts.headers || {};
this.connection = null;
this.connect = null;
}
_connect() {
if (!this.connect) {
this.connect = new Promise((resolve, reject) => {
this.connection = new WebSocket(this.cableURL, undefined, { origin: this.origin, headers: this.headers });
this.connection.onerror = (err) => {
reject(err);
};
this.connection.onclose = () => {
reject(new Error('Connection closed'));
};
this.connection.onopen = () => {
resolve(this.connection)
};
});
}
return this.connect;
}
}
and in my jest test I’ve got this
// tests/classes/action_cable.test.js
import ActionCable from '../../lib/classes/action_cable.js';
import WS from "jest-websocket-mock";
import { Server } from 'mock-socket';
let actioncableInstance = false;
beforeEach(() => {
actioncableInstance = new ActionCable('ws://localhost:1234', { origin: 'http://localhost:4321' });
});
describe('_connect', () => {
let WSServer = false;
beforeEach(() => {
WSServer = new WS('ws://localhost:1234');
});
afterEach(() => {
WS.clean();
});
describe('when WebSocket server refuses the connection', () => {
beforeEach(() => {
WSServer.on('connection', (socket) => {
console.log('received stuff');
socket.close({ wasClean: false, code: 1003, reason: "NOPE" });
});
});
test('rejects with error and calls _disconnected', async () => {
expect.assertions(1);
await expect(actioncableInstance._connect()).rejects;
});
});
});
I’ve got a mocks file that seems to no cause errors when I have it like this
// tests/__mocks__/ws.js
const WebSocket = require('mock-socket').WebSocket;
module.exports = WebSocket;
my project tree looks like this
lib
| classes
| action_cable.js
tests
| __mocks__
| ws.js
| classes
| action_cable.test.js
I’m guessing I’ve got something configured wrong but I fail to see what after half a day of trying to get my test to work for this simple case (I haven’t even begun the other cases but I think once I get the connection refused case going I’ll be able to move on to the rest). But in case there’s something else I’m getting a timeout error from my test
Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout
For a little context this is part of a bigger library of functions I’ve got for general NodeJS usage so I’m not running anything part of a NodeJS framework.
Any help or insight would be appreciated !
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (6 by maintainers)
Oh wow, thanks for your write up!!
The fact that mock-socket uses timeouts really makes it harder to write some tests ☹️
Would you be open to raising a quick PR that would add a small warning about mock timers to the readme?
Thanks again!
Got it ! maybe this should be added somewhere in the readme but basically everything I said was wrong. The issue was that in this specific test I had this setup for another test
jest.useFakeTimers();
removing the line allows the client to connect to the server.I realised this when I simply created a new
action_cable_2.js
andaction_cable_2.test.js
file using the code I provided to you (that didn’t have thejest.useFakeTimers();
line since I didn’t think it was relevant to this test [no timers to test in this function]) and noticed it simply ran (not with the right error but it was running as intended).Now I do still have an issue that I can’t seem to find any documentation on how to emulate a connection refused (like an origin header not allowed on the server) I wan work around that but if ever you have an idea of how to do this I’d be open to hearing it. I’ll close my ticket for now since I found the issue with my tests.
Thanks for checking in on my issue !