简体   繁体   English

无法使用Sinon模拟http.ServerResponse

[英]Cannot mock http.ServerResponse with Sinon

My method accepts an http.ServerResponse and calls some methods on it. 我的方法接受http.ServerResponse并在其上调用一些方法。 Looking at Sinon's docs it appears that this should be trivial. 查看Sinon的文档 ,看来这应该是微不足道的。 however, I either get TypeError: response.writeHead is not a function if I don't set up an expectation or TypeError: Attempted to wrap undefined property writeHead as function if I do set one up. 但是,如果我没有设置期望值,我将得到TypeError: response.writeHead is not a function ,或者如果我将其设置为一个,则将TypeError: Attempted to wrap undefined property writeHead as function

var http = require('http'),
    sinon = require('sinon'),
    ServerResponse = http.ServerResponse;


function SendWelcomeResponse(response) {
    var body = 'Hello World!';

    response.writeHead(200, {'Content-Type': 'text/plain', 'Content-Length': body.length});
    response.write(body);
    response.end();
}

describe('Using Sinon I should be able to mock the ServerResponse', function () {
    it.only('should mock correctly', function () {
        var mockServerResponse = sinon.mock(ServerResponse);
        mockServerResponse.expects('writeHead').once();
        SendWelcomeResponse(mockServerResponse);
    });
});

Hand rolling an object to mock 手动滚动对象进行模拟

I've just tried the two suggestions below, these gives TypeError: response.writeHead is not a function . 我刚刚尝试了以下两个建议,它们给出了TypeError: response.writeHead is not a function

var sinon = require('sinon'),
    stubServerResponse = {
        writeHead: function(statusCode, headers) {},
        write: function(body){},
        end: function() {}
    };


function SendWelcomeResponse(response) {
    var body = 'Hello World!';

    response.writeHead(200, {'Content-Type': 'text/plain', 'Content-Length': body.length});
    response.write(body);
    response.end();
}

describe('Using Sinon I should be able to mock the ServerResponse', function () {
    it.only('should mock correctly', function () {
        var mockServerResponse = sinon.mock(stubServerResponse);
        mockServerResponse.expects('writeHead').once();
        SendWelcomeResponse(mockServerResponse);
    });
});

Working! 工作!

The magic was the solutions suggested below, and using the .object property of the mock object rather than the object itself. 魔术是下面建议的解决方案,它使用模拟对象的.object属性而不是对象本身。 The following gives green tests! 以下给出绿色测试!

var sinon = require('sinon'),
    stubServerResponse = {
        writeHead: function(statusCode, headers) {},
        write: function(body){},
        end: function() {}
    };


function SendWelcomeResponse(response) {
    var body = 'Hello World!';

    response.writeHead(200, {'Content-Type': 'text/plain', 'Content-Length': body.length});
    response.write(body);
    response.end();
}

describe('Using Sinon I should be able to mock the ServerResponse', function () {
    it.only('should mock correctly', function () {
        var mockServerResponse = sinon.mock(stubServerResponse);
        mockServerResponse.expects('writeHead').once();
        SendWelcomeResponse(mockServerResponse.object);
    });
});

It looks like sinon.mock only stubs methods that are hasOwnProperty of the object you are passing it; 看起来就像sinon.mock一样,只对您要传递的对象的hasOwnProperty的方法进行存根;

https://github.com/sinonjs/sinon/blob/master/lib/sinon/extend.js#L63 https://github.com/sinonjs/sinon/blob/master/lib/sinon/extend.js#L63

I'm thinking ServerResponse.writeHead is implemented on prototype. 我认为ServerResponse.writeHead是在原型上实现的。 So that its methods are not directly mocked. 这样就不会直接模拟其方法。

An option is to create a mock object that implements writeHead , write and end , spy on those methods and make assertions on it. 一种选择是创建一个模拟对象,该对象实现writeHeadwriteend ,对这些方法进行监视并对其进行断言。 This would be a much more manual process in creating the mocked object... 这将是创建模拟对象的更多手动过程。

You can pass a dummy object that mimics ServerResponse behaviour instead of a proper ServerResponse (because they are not so easy to construct). 您可以传递模仿ServerResponse行为的虚拟对象,而不是传递适当的ServerResponse (因为它们不那么容易构造)。

Also, you should mock a method of an object, not an entire object. 另外,您应该模拟对象的方法,而不是整个对象。 And pass the object to the method, not the mock. 并将对象传递给方法,而不是模拟对象。

describe('Using Sinon I should be able to mock the ServerResponse', function () {
    it.only('should mock correctly', function () {
        serverResponse = {
            writeHead: function () {
            },
            write: function () {
            },
            end: function () {
            }
        }
        var mockServerResponse = sinon.mock(serverResponse, 'writeHead');
        mockServerResponse.expects('writeHead').once();
        SendWelcomeResponse(serverResponse);
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM