2012-04-23 14 views
7

divulgación completa ... esta es mi primera pregunta SO. Por favor, sé amable si dejo algo fuera. ;-)valor de retorno de los métodos que utilizan espiado Jasmine

estoy empezando a utilizar Jasmin para probar uno de mis objetos del lado del cliente de JavaScript. Este objeto en particular maneja el uso de un complemento jQuery llamado DataTables. El componente DataTables administrado llamará a un par de métodos de renderización personalizados para determinar qué mostrar para un par de columnas y estoy tratando de probar esos métodos.

La pregunta breve: ¿Cómo puedo probar el valor de retorno de los métodos para los que necesito poner un espía?

La historia de fondo

Aquí es una versión encogido de mi objeto 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>'; 
}; 

Así que cuando se crea un objeto de tabla, necesito para interceptar la llamada a Table.RenderIdColumn y en la tabla .renderNameColumn para que pueda afirmar los resultados. Aquí es lo que tengo en Jasmine hasta ahora:

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"); 
} 

En ambos casos de prueba, los "Resultados" variable es 'indefinido'. Necesito probar estos métodos para asegurarme de que estén representando el HTML correcto, pero parece que no puedo averiguar cómo afirmar los valores devueltos. Una vez que tengo un espía en el método, no parece devolver nada. Intenté insertar

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

Pero ninguno de ellos hizo nada ... ¿tal vez porque mis métodos son estáticos? FYI, esos métodos son estáticos porque no puedo asignar correctamente el "espía" si son métodos de instancia. El constructor de la tabla llama al complemento DataTables que hará que estos métodos sean llamados automáticamente, por lo que no puedo construir un objeto Table y luego poner un espía en esos métodos.

Respuesta

5

Cuando escribe spyOn(Table, "renderIdColumn"), está (efectivamente) reemplazando Table.renderIdColumn con una función que no devuelve nada.

Si desea afirmar que se llamó y aún devolver los resultados del original, escriba spyOn(Table, "renderIdColumn").andCallThrough().

La sintaxis .reset() usted ha mencionado solamente se restablecerá el recuento de llamadas internas de la espía (IIRC).

Cuestiones relacionadas