2012-04-23 10 views
7

Full disclosure ... questa è la mia prima domanda SO. Per favore sii gentile se lascio qualcosa fuori. ;-)Test del valore di ritorno dei metodi spiati usando Jasmine

Sto iniziando a utilizzare Jasmin per testare uno dei miei oggetti Javascript lato client. Questo oggetto in particolare gestisce l'uso di un plugin jQuery chiamato DataTables. Il componente DataTables gestito chiamerà un paio di metodi di rendering personalizzati per determinare cosa visualizzare per un paio di colonne e sto provando a testare questi metodi.

La domanda breve: Come posso verificare il valore restituito dei metodi per cui ho bisogno di mettere una spia?

La storia posteriore

Qui è una versione ridotta verso il basso del mio oggetto Javascript:

function Table(elemId) { 
    this._table = $('#'+elemId).dataTable({ 
     "aoColumnDefs": [ 
      { 
       "fnRender": function(oObj, id) { 
        return Table.renderIdColumn(oObj, id, lTable); 
       }, 
       "aTargets": ["idColumn"], 
       "bUseRendered": false 
      },{ 
       "fnRender": function(oObj, name) { 
        return Table.renderNameColumn(oObj, name, lTable); 
       }, 
       "aTargets": ["nameColumn"], 
       "bUseRendered": false 
      } 
     ], 
     "bJQueryUI": true, 
     "sPaginationType": "full_numbers" 
    }); 
} 

Table.renderIdColumn = function(oObj, id, lTable) { 
    return '<input type="checkbox" value="' id + '" />'; 
}; 

Table.renderNameColumn = function(oObj, name, lTable) { 
    var id = oObj.aData[0]; 
    return '<a href="/obj/edit/' + id + '">' + name + '</a>'; 
}; 

Così, quando la creazione di un oggetto Table, ho bisogno di intercettare la chiamata a Table.RenderIdColumn e Tabella .RenderNameColumn in modo da poter affermare i risultati. Ecco quello che ho in Jasmine finora:

describe("Table", function() { 
    var lTable; 

    // Write a DOM table that will be rendered by the jQuery DataTable plugin 
    beforeEach(function() { 
     $('<table id="storeTable"></table>').appendTo('body'); 
     var headerCellClasses = ["idColumn","nameColumn"]; 
     var headerRow = $('<tr></tr>'); 
     $.each(headerCellClasses, function(index, value) { 
      headerRow.append('<th class="' + value + '"></th>') 
     }); 
     $('<thead></thead>').append(headerRow).appendTo('#lTable'); 
     $('<tbody></tbody>').appendTo('#lTable'); 
    }); 

    afterEach(function() { 
     // First remove DataTables enhancements 
     lTable.fnDestroy(); 
     // Now remove from DOM 
     $('#lTable').remove(); 
    }); 

    describe("when edit links are shown", function() { 
     it("should render a checkbox in ID column", function() { 
      spyOn(Table, "renderIdColumn"); 
      lTable = initializeDataTable(); 
      var oSettings = lTable._table.fnSettings(); 
      var id = 1; 
      var obj = { 
       oSettings: oSettings, 
       iDataColumn: 0, 
       iDataRow: 0, 
       mDataProp: 0, 
       aData: oSettings.aoData[0]._aData 
      } 

      var expected = '<input type="checkbox" value="'+ id +'" />'; 
      expect(Table.renderIdColumn).toHaveBeenCalledWith(obj, id, lTable); 
      var results = Table.renderIdColumn(obj, id, lTable); 
      expect(results).toEqual(expected); 
     }); 
     it("should render the name column with a proper link", function() { 
      spyOn(Table, "renderNameColumn"); 
      lTable = initializeDataTable(); 
      var oSettings = lTable._table.fnSettings(); 
      var name = "Name"; 
      var obj = { 
       oSettings: oSettings, 
       iDataColumn: 3, 
       iDataRow: 0, 
       mDataProp: 3, 
       aData: oSettings.aoData[0]._aData 
      } 

      var expected = '<a href="/obj/edit/1">Name</a>'; 
      expect(Table.renderNameColumn).toHaveBeenCalledWith(obj, name, lTable); 
      var results = Table.renderNameColumn(obj, name, lTable); 
      expect(results).toEqual(expected); 
     }); 
    }); 

}); 

function initializeDataTable() { 
    // Mock the AJAX call to the server from DataTables plugin 
    spyOn($.fn.DataTable.defaults, "fnServerData").andCallFake(function(sUrl, aoData, fnCallback, oSettings) { 
     var json = { 
      iEcho: 1, 
      iTotalRecords: 1, 
      iTotalDisplayRecord: 1, 
      aaData: [ 
       [1, "Name"] 
      ] 
     } 
     fnCallback(json); 
    }); 
    return new Table("lTable"); 
} 

In entrambi i casi di test, i "risultati" variabili è 'undefined'. Ho bisogno di testare questi metodi per assicurarmi che stiano rendendo l'HTML corretto ma non riesco a capire come affermare i valori di ritorno. Una volta che ho una spia sul metodo, non sembra che restituisca nulla. Ho provato a inserire

Table.renderIdColumn.reset(); 
Table.renderNameColumn.reset(); 

Ma nessuno di questi ha fatto nulla ... forse perché i miei metodi sono statici? Cordiali saluti, quei metodi sono statici perché non posso assegnare correttamente la "spia" se sono metodi di istanza. Il costruttore Table chiama il plug-in DataTables che farà sì che questi metodi vengano chiamati automaticamente, quindi non posso costruire un oggetto Table e quindi mettere una spia su quei metodi.

risposta

5

Quando si scrive spyOn(Table, "renderIdColumn"), si sostituisce (efficacemente) Table.renderIdColumn con una funzione che non restituisce nulla.

Se si desidera affermare che è stato chiamato e restituire ancora i risultati dell'originale, scrivere spyOn(Table, "renderIdColumn").andCallThrough().

La sintassi .reset() specificata reimposterà solo i conteggi delle chiamate interne della spia (IIRC).

Problemi correlati