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!

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top