我尝试测试onmessage
是否是正确的功能。
这是一个测试:
describe(".init(address, window)", function() {
beforeEach(function() {
address = 'ws://test.address';
window = {};
e = {
data: {}
}
spyOn(window, 'WebSocket').and.returnValue(function() {return {onmessage: null}});
spyOn(subject, 'handleMessage');
});
it("should create a WebSocket client which connects to the given address", function() {
subject.init(address, window);
expect(window.WebSocket).toHaveBeenCalledWith(address);
});
it("should have onmessage method overriden with a function which handles message", function() {
ws = subject.init(address, window);
alert(JSON.stringify(ws));
ws.onmessage(e);
expect(subject.handleMessage).toHaveBeenCalledWith(e.data);
});
});
以下是实施:
FL.init = function(address, window) {
if ('WebSocket' in window) {
var ws = new WebSocket(address);
ws.onmessage = function(e) {
this.handleMessage(e.data);
};
return ws;
}
};
第一次测试通过。在第二个中,ws
是undefined
。这是为什么?我试过一个控制台new function() {return {onmessage: null}}
,它看起来应该没问题。
答案 0 :(得分:11)
我并不完全确定我是否知道您的代码应该如何表现,但是如果您需要监视WebSocket
构造函数和stub .send
方法来模拟一些传入的消息,这是如何实现它。
要监视WebSocket
,您需要致电.and.callThrough
而不是returnValue
。然而,由于抱怨缺少new
关键字(如here中所述),因此您需要伪造构造函数:
var realWS = WebSocket;
var WebSocketSpy = spyOn(window, "WebSocket").and.callFake(function(url,protocols){
return new realWS(url,protocols);
});
要为传入的消息制作间谍,您可以这样做
var onmessageCallbackSpy = jasmine.createSpy('onmessageCallback');
你也可以监视.send
方法,并提供一些模拟的回复:
var sendSpy = spyOn(WebSocket.prototype, "send").and.callFake(function(outMsg){
// process/check outgoing message
// setTimeout, or call it immediately
this.onmessage("mock message goes here");
});
但在使用WebSocket.prototype
替换之前,请务必使用WebSocketSpy
。
如此完整的工作示例,应该如下所示:
it("should spy and callFake WebSocket constructor, and stub prototype methods", function (done) {
var realWS= WebSocket;
var sendSpy = spyOn(WebSocket.prototype, "send").and.callFake(function(outMsg){
if(outMsg == "outgoing message"){
this.onmessage("incoming mocked message goes here");
}
});
// var messageSpy = spyOn(WebSocket.prototype, "onmessage");//.and.returnValue("mock message goes here");
var WSSpy = spyOn(window, "WebSocket").and.callFake(function(url,protocols){
return new realWS(url,protocols);
});
var onmessageCallbackSpy = jasmine.createSpy('onmessageCallback');
// Your code
// (function init(url, onmessageCallbackSpy){
var ws = new WebSocket("ws://some/where");
ws.onmessage = onmessageCallbackSpy;
// code that results with receiving a message
// or mocked send, that calls `.onmessage` immediately
ws.send("outgoing message");
// })();
expect(WSSpy).toHaveBeenCalledWith("ws://some/where");
expect(onmessageCallbackSpy).toHaveBeenCalledWith("mock message goes here");
done();
});
答案 1 :(得分:3)
我遇到它试图模仿websocket进行茉莉花测试。这是一个使用相当广泛的模拟窗口的解决方案.WebSocket。
var socketMock;
var windowMock;
var address = 'ws://test.address';
describe(".init(address, window)", function() {
beforeEach(function() {
var WebSocket = jasmine.createSpy();
WebSocket.and.callFake(function (url) {
socketMock = {
url: url,
readyState: WebSocket.CONNECTING,
send: jasmine.createSpy(),
close: jasmine.createSpy().and.callFake(function () {
socketMock.readyState = WebSocket.CLOSING;
}),
// methods to mock the internal behaviour of the real WebSocket
_open: function () {
socketMock.readyState = WebSocket.OPEN;
socketMock.onopen && socketMock.onopen();
},
_message: function (msg) {
socketMock.onmessage && socketMock.onmessage({data: msg});
},
_error: function () {
socketMock.readyState = WebSocket.CLOSED;
socketMock.onerror && socketMock.onerror();
},
_close: function () {
socketMock.readyState = WebSocket.CLOSED;
socketMock.onclose && socketMock.onclose();
}
};
return socketMock;
});
WebSocket.CONNECTING = 0;
WebSocket.OPEN = 1;
WebSocket.CLOSING = 2;
WebSocket.CLOSED = 3;
windowMock = {
WebSocket: WebSocket
};
spyOn(subject, 'handleMessage');
});
it("should create a WebSocket client which connects to the given address", function() {
subject.init(address, windowMock);
expect(windowMock.WebSocket).toHaveBeenCalledWith(address);
});
it("should have onmessage method overriden with a function which handles message", function() {
var message = 'hello socket';
subject.init(address, window);
// pretend the socket connected (optional)
socketMock._open();
// pretend the socket got a message
socketMock._message(message)
expect(subject.handleMessage).toHaveBeenCalledWith(message);
});
});