Wednesday 24 May 2017

Sinon.js spy.called not working on RPCs

Background

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.

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 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;
            } )
            .catch( err => done( err ) );
    } );

} );

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

Problem

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 the openSpy.called is always false (even though the spied method was called!).

What I tried

  1. Removing 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.
  2. Using a 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 ...
  3. Using setTimeout. I thought that perhaps the reason this was happening was because I am making the test to soon, so I created a setTimeout with 0 evolving the expect statement. Also failed.

Question

  1. What am I doing wrong?
  2. How can i fix it?


via Flame_Phoenix

No comments:

Post a Comment