2012-04-23 26 views
7

Tiết lộ đầy đủ ... đây là câu hỏi SO đầu tiên của tôi. Hãy tử tế nếu tôi để lại bất cứ điều gì. ;-)Kiểm tra giá trị trả về của các phương thức gián điệp bằng cách sử dụng Jasmine

Tôi bắt đầu sử dụng Jasmin để kiểm tra một trong các đối tượng Javascript phía máy khách của mình. Đối tượng này đặc biệt quản lý việc sử dụng một plugin jQuery có tên là DataTables. Thành phần DataTables được quản lý sẽ gọi một vài phương thức hiển thị tùy chỉnh để xác định những gì sẽ hiển thị cho một vài cột và tôi đang cố gắng thử nghiệm các phương thức đó.

Câu hỏi ngắn: Làm cách nào tôi có thể kiểm tra giá trị trả về của các phương pháp mà tôi cần đặt gián điệp?

Câu chuyện trở lại

Dưới đây là một phiên bản thu nhỏ xuống của đối tượng javascript của tôi:

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>'; 
}; 

Vì vậy, khi tạo một đối tượng Table, tôi cần phải ngăn chặn các cuộc gọi đến Table.RenderIdColumn và Bảng .renderNameColumn để tôi có thể khẳng định kết quả. Dưới đây là những gì tôi có trong Jasmine cho đến thời điểm này:

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

Trong cả hai trường hợp kiểm tra, biến "kết quả" là 'không xác định'. Tôi cần phải kiểm tra các phương pháp này để đảm bảo rằng chúng đang hiển thị đúng HTML nhưng tôi không thể tìm ra cách để xác nhận các giá trị trả lại. Một khi tôi có một gián điệp về phương pháp, nó dường như không trả lại bất cứ điều gì. Tôi đã thử chèn

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

Nhưng không ai trong số đó làm bất cứ điều gì ... có thể vì phương pháp của tôi là tĩnh? FYI, những phương pháp đó là tĩnh bởi vì tôi không thể chỉ định đúng "gián điệp" nếu chúng là các phương thức thể hiện. Trình xây dựng bảng gọi plugin DataTables sẽ khiến các phương thức này được gọi tự động vì vậy tôi không thể xây dựng một đối tượng Table và sau đó đặt một điệp viên trên các phương thức đó.

Trả lời

5

Khi bạn viết spyOn(Table, "renderIdColumn"), bạn (có hiệu quả) thay thế Table.renderIdColumn bằng hàm không trả lại bất kỳ thứ gì.

Nếu bạn muốn khẳng định nó đã được gọi và vẫn trả lại kết quả của bản gốc, hãy viết spyOn(Table, "renderIdColumn").andCallThrough().

Cú pháp .reset() bạn đã đề cập sẽ chỉ đặt lại số cuộc gọi nội bộ của spy (IIRC).

Các vấn đề liên quan