2014-04-18 2 views
5

onmessage이 적절한 기능인지 테스트 해 봅니다.Jasmine으로 JavaScript에서 WebSocket 스터 빙

FL.init = function(address, window) { 
    if ('WebSocket' in window) { 
    var ws = new WebSocket(address); 
    ws.onmessage = function(e) { 
     this.handleMessage(e.data); 
    }; 
    return ws; 
    } 
}; 

첫 번째 테스트가 통과 : 여기

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

의 구현 : 여기

테스트이다. 두 번째로 wsundefined입니다. 왜 그런가요? 콘솔 new function() {return {onmessage: null}}에서 시도하고 확인해야합니다.

답변

8

당신의 코드가 어떻게 동작해야하는지 알지 못하지만, WebSocket 생성자와 스터브 .send 메쏘드를 모방하기 위해 스푸핑해야 할 필요가있는 경우, 여기에서 그것을 달성하는 방법이 있습니다.

WebSocket에 간첩하려면 returnValue 대신 .and.callThrough으로 전화해야합니다. 그러나 new 키워드 (here에서 언급 된)의 부족에 대해 불만과 함께이 발생할 수 있으므로 가짜 생성자가 필요 : 당신은 단순히

var onmessageCallbackSpy = jasmine.createSpy('onmessageCallback'); 
을 할 수있는 수신 메시지에 대한 스파이를 만들려면

var realWS = WebSocket; 
var WebSocketSpy = spyOn(window, "WebSocket").and.callFake(function(url,protocols){ 
    return new realWS(url,protocols); 
}); 

는 또한 .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"); 
}); 

WebSocketSpy으로 바꾸기 전에 WebSocket.prototype을 사용해야합니다.

그래서 전체 작업 예를 들어, 다음과 같아야합니다

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

내가 자스민 시험을위한 웹 소켓을 조롱하려고 가로 질러왔다. 꽤 광범위한 mock window.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); 
    }); 
});