无法使用Sinon

时间:2015-11-13 16:02:29

标签: javascript node.js mocha sinon

我的方法接受http.ServerResponse并在其上调用一些方法。看Sinon's docs看来这应该是微不足道的。但是,如果我没有设定期望,我会获得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);
    });
});

将对象滚动到模拟

我刚刚尝试了以下两条建议,这些建议提供了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);
    });
});

工作!

魔术是下面建议的解决方案,并使用模拟对象的.object属性而不是对象本身。以下是绿色测试!

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

2 个答案:

答案 0 :(得分:0)

看起来只有sinon.mock的存根方法是你传递它的对象的hasOwnProperty;

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

我认为ServerResponse.writeHead是在原型上实现的。所以它的方法不是直接嘲笑的。

一个选项是创建一个实现writeHeadwriteend的模拟对象,监视这些方法并对其进行断言。在创建模拟对象时,这将是一个更加手动的过程......

答案 1 :(得分:0)

您可以传递一个模仿ServerResponse行为的虚拟对象,而不是正确的ServerResponse(因为它们不容易构造)。

此外,您应该模拟对象的方法,而不是整个对象。并将对象传递给方法,而不是模拟。

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