javascript
  • testing
  • websocket
  • jasmine
  • stub
  • 2014-04-18 4379 views 5 likes 
    5

    Tôi thử kiểm tra xem onmessage có phải là một chức năng thích hợp không.Chèn WebSocket bằng JavaScript với Jasmine

    Dưới đây là một thử nghiệm:

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

    Đây là việc thực hiện:

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

    Các thử nghiệm đầu tiên trôi qua. Trong giây, wsundefined. Tại sao vậy? Tôi đã thử trong một giao diện điều khiển new function() {return {onmessage: null}} và có vẻ như nó sẽ là ok.

    Trả lời

    8

    Tôi không hoàn toàn chắc chắn rằng tôi đã tìm ra cách mã của bạn hoạt động, nhưng nếu bạn cần theo dõi phương thức WebSocket và phương pháp để giả lập một số thư đến, dưới đây là cách thực hiện.

    Để theo dõi WebSocket, bạn cần phải gọi .and.callThrough thay vì returnValue. Tuy nhiên nó cho kết quả với than phiền về việc thiếu new từ khóa (như đã đề cập trong here), vì vậy bạn cần phải giả các nhà xây dựng:

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

    Để thực hiện một điệp viên cho tin nhắn đến bạn chỉ có thể làm

    var onmessageCallbackSpy = jasmine.createSpy('onmessageCallback'); 
    

    Bạn cũng có thể do thám .send phương pháp, và cung cấp một số phản ứng chế giễu với:

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

    Nhưng hãy đảm bảo sử dụng WebSocket.prototype, trước khi bạn thay thế bằng WebSocketSpy.

    Vì vậy, đầy đủ ví dụ làm việc, nên trông như thế này:

    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

    tôi đi qua nó cố gắng thử một WebSocket để thử nghiệm hoa nhài. Đây là một giải pháp sử dụng khá nhiều cửa sổ 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); 
        }); 
    }); 
    
    Các vấn đề liên quan