Sinon: Spy on WebSocket construction does not work

Created on 4 May 2015  路  2Comments  路  Source: sinonjs/sinon

Reposting this SO question:

I am trying to spy on WebSocket construction with the following code (requirebin):

sinon = require('sinon');

sinon.spy(window, 'WebSocket');
// throws an error (see console)
new window.WebSocket("ws://example.com");

In Chrome it fails with Uncaught TypeError: Failed to construct 'WebSocket': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

In Safari and PhantomJs it fails with TypeError: Attempted to wrap object property WebSocket as function

What am I doing wrong?

Question

Most helpful comment

Native objects are notoriously unreliable as spying/stubbing targets.

If you're working with a level of indirection like Socket.IO, then I'd recommend targeting that for spying/stubbing. There are examples of how to do this with Sinon.JS.

If you're working closer to the metal, then I'd recommend using a very thin wrapper around the target natives, to allow spying/stubbing.

I created wrapple for this purpose, but it's simple enough to create your own.

// totally making things up here
function WrapWebSocket(){
    return window.WebSocket;
}

// in your code
function init(){
    var WS = WrapWebSocket();
    var ws = new WS();
}

// in your test
var spy = sinon.spy();
sinon.stub(window, 'WrapWebSocket', function(){
    return spy;
});
init();
assert(spy.calledWith('someurl');

All 2 comments

Native objects are notoriously unreliable as spying/stubbing targets.

If you're working with a level of indirection like Socket.IO, then I'd recommend targeting that for spying/stubbing. There are examples of how to do this with Sinon.JS.

If you're working closer to the metal, then I'd recommend using a very thin wrapper around the target natives, to allow spying/stubbing.

I created wrapple for this purpose, but it's simple enough to create your own.

// totally making things up here
function WrapWebSocket(){
    return window.WebSocket;
}

// in your code
function init(){
    var WS = WrapWebSocket();
    var ws = new WS();
}

// in your test
var spy = sinon.spy();
sinon.stub(window, 'WrapWebSocket', function(){
    return spy;
});
init();
assert(spy.calledWith('someurl');

Thanks for the explanation, now I understand what the problem is.

Wrapple seems like a reasonable workaraound. Thanks again!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kbirger picture kbirger  路  3Comments

kevinburkeshyp picture kevinburkeshyp  路  4Comments

ALeschinsky picture ALeschinsky  路  4Comments

NathanHazout picture NathanHazout  路  3Comments

stevenmusumeche picture stevenmusumeche  路  3Comments