使用 Sinon 创建 document.getSelection 的存根

Creating a stub of document.getSelection using Sinon

我的函数(您可以在下面找到)使用 document.getSelection 获取屏幕上当前选定的文本。我需要能够指定 document.getSelection 的值,以便测试我的函数。

我试过像这样创建存根:

document.getSelection = sinon.stub(document, "getSelection", function() { return "Hello world!" } );

var selection = wysiwyg.getCurrentRange();

然而,它只是得到 undefined 供选择。有人可以告诉我我做错了什么吗?

这是我正在测试的方法:

 Wysiwyg.prototype.getCurrentRange = function() {
    var sel, range;
    if ( window.getSelection ) {
        sel = window.getSelection();
        if ( sel.getRangeAt && sel.rangeCount ) {
            range = sel.getRangeAt( 0 );
        }
    } else if ( document.selection ) {
        range = document.selection.createRange();
    }

    return range;
 };

您的代码中有 4 个错误:

  1. 第一个很明显。如果你想创建一个存根 window.getSelection 你应该将它应用到 window.getSelection (不是 document.getSelection)。
  2. 第二个也很明显。 原来selrangeundefined。你替代 document.getSelection 具有 return 字符串的函数 'Hello world!'(参见第 4 行)。因此 sel 等于 'Hello world!' 和 sel.getRangeAt 连同 sel.rangeCountundefined。因此,整个表达式 sel.getRangeAt && sel.rangeCountfalserange,结果是 return 仍然是 undefined(您得到的确切结果)。
  3. 您应该将 sinon.stub 的结果分配给 一个新变量(不是替换方法)。
  4. 总是在测试结束时恢复原来的方法。

另请注意,如果方法未定义,则不能将存根应用于该方法。

考虑到以上所有情况,没有存根的解决方案更好。

要测试正向分支,您可以使用

var getRangeAtResult = 'getRangeAt Expected Result';
var getRangeAtSpy = sinon.spy(function() {
    return getRangeAtResult;
});

var windowGetSelectionBackUp = window.getSelection;
window.getSelection = function() {
    return {
        getRangeAt: getRangeAtSpy,
        rangeCount: true
    };
};

wysiwyg.getCurrentRange().should.be.equal(getRangeAtResult);

getRangeAtSpy.withArgs(0).called.should.be.equal(true);
window.getSelection = windowGetSelectionBackUp;

如果您确定 document.getSelection 已定义,您可以使用 stub

var getRangeAtResult = 'getRangeAt Expected Result';
var getRangeAtSpy = sinon.spy(function() {
    return getRangeAtResult;
});

var documentGetSelectionStub = sinon.stub(document, 'getSelection', function() {
    return {
        getRangeAt: getRangeAtSpy,
        rangeCount: true
    };
});

wysiwyg.getCurrentRange().should.be.equal(getRangeAtResult);

getRangeAtSpy.withArgs(0).called.should.be.equal(true);
documentGetSelectionStub.restore();

要测试负分支,您可以使用

var createRangeResult = 'createRange Expected Result';
var createRangeSpy = sinon.spy(function() {
    return createRangeResult;
});

var documentSelectionBackUp = document.selection;
document.selection = function() {
    return {createRange: createRangeSpy};
};

wysiwyg.getCurrentRange().should.be.equal(createRangeResult);

createRangeSpy.called.should.be.equal(true);
document.selection = documentSelectionBackUp;