On me fait une petite fonction qui émet des messages via des sockets et j’essaye de le tester en utilisant mocha et sinon:
const myFun = socket => { socket.emit("first", "hello World!"); //some random amount of time passes socket.emit("second", "hello Moon!"); //other random amount of time passes socket.emit("third", "hello Mars? Venus? I dunno..."); };
En utilisant sinon je peux transmettre à ma fonction un fakeSocket:
const fakeSocket = { emit: sinon.spy() };
Et vérifiez si j’émets ou non les messages.
Le problème ici est que je ne sais pas quand mon test se terminera . Parce que myFun
ne myFun
pas de promesse et que je n’ai pas de message final , je ne sais pas comment dire à mocha que j’ai envoyé tous les messages que je voulais et que le test devrait se terminer.
const chai = require("chai"); const expect = chai.expect; const chaiAsPromised = require("chai-as-promised"); chai.use(chaiAsPromised); const sinon = require("sinon"); const sinonChai = require("sinon-chai"); chai.use(sinonChai); describe("myFun", () => { const fakeSocket = { emit: sinon.spy() }; it("receive first message", done => { myFun(fakeSocket); setTimeout(() => { try{ expect(fakeSocket.emit).to.have.been.calledThrice; done(); }catch(err){ done(err); } }, 1000); //1 seconds should be more than enough to let the test complete. }); });
J’utilise un setTimeout
avec un try catch
pour tester le code, ce qui est honnêtement assez horrible.
setTimeout
? Si vous savez qu’un message particulier est toujours défini en dernier, vous pouvez demander à Sinon d’appeler une fonction lorsque ce message est émis. Cette fonction peut être la fonction de rappel de Mocha pour les tests asynchrones:
describe("myFun", function() { // Extend timeout and "slow test" values. this.timeout(3000).slow(10000); const fakeSocket = { emit: sinon.stub() } it('should emit a certain final message', done => { fakeSocket.emit.withArgs('third', 'hello Mars? Venus? I dunno...') .callsFake(() => done()); myFun(fakeSocket); }); });
Donc, si socket.emit()
est appelé avec les arguments 'third', 'hello Mars?...'
, Sinon appellera une fonction qui appelle le rappel done
, signalant à Mocha que le test est terminé.
Lorsque, pour une raison quelconque, ce message n’est pas émis, done
n’est jamais appelé et le test expire (au bout de 3 secondes), ce qui indique que le test a échoué ou qu’il a pris plus de temps que prévu.
Si vous ne savez pas ce que le premier argument de socket.emit()
sera pour le dernier message, seul le message lui-même, le test devient ceci:
it('should emit a certain final message', done => { fakeSocket.emit.callsFake((name, msg) => { if (msg === 'hello Mars? Venus? I dunno...') { done(); } }); myFun(fakeSocket); })