You have to spy on jquery.prototype.dataTable
, cause this will be the function that will be used when calling actualTable.dataTable()
.
var createDateTableFunctionSpy = sinon.spy($.prototype, "dataTable");
Question
i am wanting to test a function to be sure the jquery.dataTable is being called when I should be. I want to use a sinon spy to do this.
I am using typescript and I have a dataTableManager that will actually create the datatable for me. I am using qunit as the testing framework
how can I spy on this? right now I am getting the following error
Attempted to wrap undefined property dataTable as function
here is my test
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);
});
here is my constructor
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;
}
and here is the create function I am trying to test
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);
};
any ideas on how I can spy on the actualTable.dataTable(this.options); call would be great, thanks!
Solution
You have to spy on jquery.prototype.dataTable
, cause this will be the function that will be used when calling actualTable.dataTable()
.
var createDateTableFunctionSpy = sinon.spy($.prototype, "dataTable");
OTHER TIPS
You are spying on the wrong object - you are setting the spy on the return value of the jquery function result, not on the jQuery function itself.
sinon.spy( $("#testTable") ) // Returns a new object with a spy on it
This returns an object that has a spy, but when your code runs, this function will be called again and return a new object that does not have a spy.
The best solution that I've found is to stub out $ and return some fake object. Any call to $() will return this object and you can 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);
The problem with this approach is that all of the $() methods are hidden by the stub, so if your code tries to use other jQuery methods then you'll need to stub them as well. You may be able to work around this by using a spy.