2014-09-18 2 views
3

Мой проект использует AngularJS + Kendo-UI. Я пытаюсь проверить один из моих контроллеров, который использует Кендо-UI сетки:Единичное тестирование Угловой контроллер, который использует Kendo Grid/Datasource

angular.module('myApp')('DevicesCtrl', function ($scope) { 

    $scope.gridOptions = { 
     dataSource: { 
      transport: { 
       read: { 
        url: "/devices", 
        dataType: "json" 
       } 
      }, 
      change: function(){ 
       var view = this.view(); 
       $scope.devices = []; 

       $.each(view, function(i, v) { 
        $scope.devices.push({id: v.id, description: v.name, status: v.status == 0 ? "failure" : "success"}); 
       }); 
       $scope.$apply(); 
      } 
     }, 
     columns: [ 
      { 
       field: "name", 
       title: "Name", 
       width: 250, 
       template: function (item) { 
        var itemStatus = item.status == 0 ? 'failure' : 'success'; 
        return '<div label size="small" operation="' + itemStatus + '" label="' + item.name + '"></div>'; 
       } 
      }, 
      { 
       field: "status", 
       title: "Status" 
      } 
     ] 
    }; 
}); 

Когда я написал модульное тестирование, я ожидал, что запрос GET будет называться:

describe('deviceCtrl', function() { 

    var scope, deviceCtrl, httpBackend, timeout; 

    beforeEach(module("myApp")); 
    beforeEach(module('src/modules/devices/views/device.html')); 

    beforeEach(inject(function ($controller, $rootScope, $httpBackend, $timeout, $state) { 
     scope = $rootScope.$new(); 

     httpBackend = $httpBackend; 
     timeout = $timeout; 

     httpBackend.expectGET('languages/en_US.json').respond({}); 

     deviceCtrl = $controller("DeviceCtrl", { 
      $scope: scope 
     }); 

     $state.go("devices"); 
     timeout.flush() 

    })); 

    it('should load the switch list', function() { 

     httpBackend.expectGET("/devices").respond(
      [{"id":"1","name":"name 1","status":"1"}, 
      {"id":"2","name":"name 2","status":"2"}] 
     ); 

     httpBackend.flush(); 

    }); 

}); 

Но ожидание никогда не выполняется, запросы не принимаются. Итак, мой вопрос: есть ли способ сделать Kendo Grid/Datasource для этого вызова, чтобы я мог его издеваться?

Я видел несколько примеров того, как это сделать, используя Mockjax (http://www.telerik.com/forums/best-practice-mocking-with-datasource), но я бы предпочел использовать угловые библиотеки для этого.

ответ

6

После многих исследований я смог найти несколько способов тестирования контроллеров, которые используют Kendo Datasource.

У Kendo есть свой собственный способ сделать звонки Ajax для получения данных и не использовать регулярные Angular $ http для этого, поэтому немного сложнее протестировать, используя угловые инструменты (угловые-mocks). Перейдем к следующим вариантам:

1 - Использовать регулярный Угловой способ совершения вызовов Ajax.

Кендо позволяет нам изменить способ извлекает данные, поэтому вместо того, чтобы делать:

dataSource: new kendo.data.DataSource({ 
      transport: { 
       read: { 
        url: "/devices, 
        dataType: "json" 
       } 
      }, 
      change: function(){ 
       var view = this.view(); 
       $scope.devices = []; 

       $.each(view, function(i, v) { 
        $scope.devices.push({id: v.id, description: v.name, status: v.status == 0 ? "failure" : "success"}); 
       }); 
       $scope.$apply(); 
      } 
     }); 

Мы изменимся на:

dataSource: new kendo.data.DataSource({ 
      transport: { 
       read: function(options){ 
        $http.get("/devices").then(function(response){ 
         options.success(response.data); 
         $scope.devices = []; 
         response.data.forEach(function(v){ 
          $scope.devices.push({id: v.id, description: v.name, status: v.status == 0 ? "failure" : "success"}); 
         }); 
        }); 
       } 
      } 
     }); 

Тогда мы можем использовать регулярный $ httpBackend.expectGET (URL), чтобы высмеять вызов Ajax. Мне лично нравится этот подход, потому что у нас больше контроля. Ps .: используя переменные «опции» внутри функции, мы имеем доступ к фильтру Grid, сортировке и подкачки.

2 - Откажитесь от вызова Kendo Ajax.

Таким образом, мы почти ничего не меняем в контроллере, но только что изменилось, чтобы создать новый источник данных, используя новый файл kendo.data.DataSource ({}) вместо простого прохождения параметров. Этому требовалось, потому что мы вызываем функцию чтения внутри тестового примера. Я пробовал разные способы издеваться над этим запросом Ajax, но единственный, с которым я мог бы работать, - использовать инструмент под названием Jasmine-Ajax. И в тестовом случае мы бы написали что-то вроде:

var request = jasmine.Ajax.requests.mostRecent(); 
request.response(MockData); 

Я надеюсь, что это может помочь другим людям.

Смежные вопросы