Sinon.js spy.called does not work on RPC

Background

I have a server that registers some RPCs using the crossbar and a test that tries to make sure that the RPCs are called using synon.

code

server.js

"use strict"; const autobahn = require( "autobahn" ); const server = () => { const open = () => console.log( "Hello world" ); const start = () => new Promise( fulfil => { const connection = new autobahn.Connection( { "url": "ws://localhost:8080/ws", "realm": "realm1" } ); connection.onopen = session => { session.register( "server.open", open ) .then(() => fulfil()) .catch(console.log); }; connection.open(); } ); //removing Object.freeze won't help =( return Object.freeze({ start, open }); }; module.exports = server; 

This server simply connects to the crossbar and then registers RPC open .

Now my test case. I use mocha with chai:

test.js

 "use strict"; const expect = require( "chai" ) .expect; const autobahn = require( "autobahn" ); const sinon = require( "sinon" ); const serverFactory = require( "./server.js" ); describe( "server", () => { const server = serverFactory(); const crossbar = { connection: undefined, session: undefined }; const connectToCrossbar = () => new Promise( fulfil => { crossbar.connection = new autobahn.Connection({ "url": "ws://localhost:8080/ws", "realm": "realm1" }); crossbar.connection.onopen = session => { crossbar.session = session; fulfil(); }; crossbar.connection.open(); } ); before( "start server", done => { server.start() .then( connectToCrossbar ) .then( done ) .catch( err => done( err ) ); } ); it( "should open", done => { const openSpy = sinon.spy( server, "open" ); crossbar.session.call( "server.open", [] ) .then( () => { expect( openSpy.called ).to.be.true; done(); } ) .catch( err => done( err ) ); } ); } ); 

This test also opens a connection to the crossbar and then calls the open method on the server.

Problem

The problem is that although I see Hello World console.log, proving that the method is actually executed, my test always fails because openSpy.called always false (although the spied method was called!).

What i tried

  • Uninstall Object.freeze . I understand that spies and stubs actually replace the functions and objects that they monitor, but in this case it did not help.
  • Using stub instead of spy . When my spy was not working, I tried replacing the open method with stub and using callsFake to complete the test. Unfortunately, callsFake never called ...
  • Using setTimeout . I thought that maybe the reason is that I am doing the test soon, so I created setTimeout from 0 , developing the expect statement. Also failed.

Question

  • What am I doing wrong?
  • How can i fix this?
+5
source share
2 answers

Renouncement

This solution is based on the tests and knowledge that I have with the crossbar. If I'm wrong, please feel free to correct me.

My conclusion

Among many other crossbar problems, crossbar is one of them - the inability to perform any kind of tests. autobahn , being a library for crossbar , shares these issues.

The reason my code is not working is because another process is actually calling my open function instead of my application. Thus, the testing process does not know that the function is called.

The solution for this is to force the open function to return the result, and then check to see if we get the result:

 it( "should be able to call registered RPCs", done => { server.getSession().call( "test1", [] ) .then( response => { expect( response ).to.eql( "Hello World" ); done(); } ) .catch( err => done( err ) ); } ); 

In reality, using this middleware is getting harder to check ... but at least now I have a way!

+1
source

According to Mocha's docs for testing asynchronous code :

By adding a callback (usually called done) to it, Mocha will know that he needs to wait until this function is called to complete the test.

You do not call done() after calling expect() . Therefore, Piss believes that your test has not yet been done. This should solve your problem.

 it( "should open", done => { const openSpy = sinon.spy( server, "open" ); crossbar.session.call( "server.open", [] ) .then( () => { expect( openSpy.called ).to.be.true; done(); // You seem to have missed this statement here } ) .catch( err => done( err ) ); } ); 
0
source

Source: https://habr.com/ru/post/1268164/


All Articles