I have a server that registers some RPCs using crossbar, and a test that is trying to make sure that the RPCs are being called using sinon.
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 the open
RPC.
Now my test case. I am using 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 opens a connection to the crossbar as well and then calls the open
method on the server.
The problem is that even though I see the Hello World
console.log, proving that the method was in fact executed, my test always fails because of the openSpy.called
is always false
(even though the spied method was called!).
Object.freeze
. I understand spies and stubs actually replace the functions and objects they are spying on, but in this case, it didn't help. stub
instead of a spy
. When my spy didn't work, I tried replacing the open
method with a stub
and use the callsFake
to finish the test. Unfortunately callsFake
never seems to be called ...setTimeout
. I thought that perhaps the reason this was happening was that I am making the test to soon, so I created a setTimeout
with 0
evolving the expect
statement. Also failed.This solution is built upon the testing and knowledge that I have with crossbar. If I am wrong, please feel free to correct me.
Among many other problems crossbar
has, one of them is the inability to do any kinds of tests. autobahn
, being a library for crossbar
shares these problems.
The reason my code doesn't work its because another process is actually calling my open
function instead of my application. Thus the process running the test never knows that the function was called.
The solution for this, is to make the open
function return a result, and then test if we receive 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 everything is harder to test ... but at least now I have a way!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With