javascript - Sinon.js spy.called 不适用于 RPC

标签 javascript mocha.js sinon crossbar autobahnjs

背景

我有一个使用 crossbar 注册一些 RPC 的服务器,以及一个试图确保使用 sinon 调用 RPC 的测试。

代码

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;

此服务器简单地连接到交叉开关,然后注册 open RPC。

现在是我的测试用例。我正在使用 mocha 和 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 ) );
    } );

} );

此测试也打开到 crossbar 的连接,然后调用服务器上的 open 方法。

问题

问题是,即使我看到 Hello World console.log,证明该方法实际上已执行,但由于 openSpy.called,我的测试总是失败> 始终为 false(即使调用了侦测方法!)。

我尝试了什么

  1. 删除 Object.freeze。我知道 spy 和 stub 实际上取代了他们正在监视的函数和对象,但在这种情况下,它没有帮助。
  2. 使用stub 而不是spy。当我的 spy 不起作用时,我尝试用 stub 替换 open 方法并使用 callsFake 来完成测试。不幸的是,callsFake 似乎从未被调用过......
  3. 使用setTimeout。我认为发生这种情况的原因可能是我即将进行测试,所以我创建了一个 setTimeout0 进化了 expect陈述。也失败了。

问题

  1. 我做错了什么?
  2. 我该如何解决?

最佳答案

免责声明

此解决方案基于我对 crossbar 的测试和了解。如果我错了,请随时纠正我。

我的结论

crossbar 的许多其他问题中,其中之一是无法进行任何类型的测试。 autobahn,作为crossbar 的库,也存在这些问题。

我的代码不起作用的原因是另一个进程实际上正在调用我的 open 函数而不是我的应用程序。因此运行测试的进程永远不知道函数被调用了。

解决办法是让open函数返回一个结果,然后测试我们是否收到结果:

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 ) );
} );

在现实中使用这个中间件一切都很难测试......但至少现在我有办法了!

关于javascript - Sinon.js spy.called 不适用于 RPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44152870/

相关文章:

javascript - 如何从 href 链接获取页码或特定参数

javascript - 带直播的VideoJs

javascript - Cypress :为数组的每个元素创建一个 it 测试

javascript - 如何使 Mocha 的 grep 选项在浏览器中工作

javascript - 如何用 Jest stub 类的所有方法?

javascript - 有没有办法在javascript中捕获后退按钮事件?

javascript - Chai assert.deepEqual 在使用 atob 时抛出错误 "TypeError: Right-hand side of ' instanceof' is not an object"

node.js - 如何使用 sinon stub NodeJS "required"构造函数?

javascript - 如何正确 stub 作为另一个 Promise 一部分的 Promise 对象

javascript - 单元测试 Typescript 装饰器