javascript - 使用 sinon.js 监听 $.dataTables 函数
我想测试一个函数,以确保在我应该调用 jQuery.dataTable 时它被调用。我想使用 sinon spy 来做到这一点。
我正在使用 TypeScript,我有一个 dataTableManager,它实际上会为我创建数据表。我使用 QUnit 作为测试框架。
我如何监视这个?现在我遇到以下错误
Attempted to wrap undefined property dataTable as function
这是我的测试
test("DataTableIsCalledWithOptionsWhenIdIsFoundOnThePage", function () {
// arrange
$("#qunit_fixture").append("<table id='#testTable'></table>");
var createDateTableFunctionSpy = sinon.spy($("#testTable"), "dataTable");
var customOptions = {
"iDisplayLength": 200,
"aoColumns": [
{ sWidth: '3%' },
{ sWidth: '47%' },
{ sWidth: '12%' },
{ sWidth: '17%' },
{ sWidth: '14%' },
{ sWidth: '7%' }],
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [0, 5] }
]
};
var dataTableManager = new DataTableManager($, "#testTable", customOptions);
// act
dataTableManager.createDataTable();
// assert
ok(createDateTableFunctionSpy.called);
});
这是我的构造函数
constructor(jQuery: JQueryStatic, tableId: string, customOptions: DataTables.Options){
var self = this;
self.jQuery = jQuery;
self.options = {};
self.jQuery.extend(self.options, DataTableManager.defaultOptions, customOptions);
self.tableId = tableId;
}
这是我正在尝试测试的创建函数
createDataTable = function () {
// if it doesn't exist on the dom return
var actualTable = this.jQuery(this.tableId);
if (actualTable.length == 0) {
return;
}
// create the data table with options
var newDataTable = actualTable.dataTable(this.options);
};
如果有办法监视实际的 actualTable.dataTable(this.options); 调用,那就太好了,谢谢!
答案#1
你必须监视 jquery.prototype.dataTable,因为这是在调用 actualTable.dataTable() 时将会使用的函数。
var createDateTableFunctionSpy = sinon.spy($.prototype, "dataTable");
答案#2
你正在监视错误的对象——你是在监视 jQuery 函数结果的返回值,而不是 jQuery 函数本身。
sinon.spy( $("#testTable") ) // Returns a new object with a spy on it
这会返回一个有间谍的对象,但当你的代码运行时,这个函数将再次被调用并返回一个没有间谍的新对象。
我找到的最好解决方案是对 $进行存根并返回一些假的对象。对 $() 的任何调用都会返回这个对象,并且你可以对它进行监视。
$_stub = sinon.stub(window, '$');
dt = { dataTable: function(){} }
$_stub.withArgs("#testTable").returns(dt); // Return fake object when $() is called
dt_spy = sinon.spy(dt, 'dateTable');
<your code>
assert(dt_spy.calledOnce);
这种方法的问题在于所有的 $() 方法都被存根隐藏了,因此如果你的代码尝试使用其他 jQuery 方法,你也需要对它们进行存根。你可能可以通过使用间谍来解决这个问题。
