【问题标题】:Unit testing Angular Controller that uses Kendo Grid/Datasource单元测试使用 Kendo Grid/Datasource 的 Angular 控制器
【发布时间】:2014-09-18 18:55:19
【问题描述】:

我的项目正在使用 AngularJS + Kendo-UI。我正在尝试测试我的一个使用 Kendo-UI 网格的控制器:

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) 的示例,但我更喜欢使用角度库来做到这一点。

【问题讨论】:

    标签: javascript angularjs unit-testing kendo-ui kendo-grid


    【解决方案1】:

    经过大量研究,我可以找到一些方法来测试使用 Kendo 数据源的控制器。

    Kendo 有自己的方式来进行 Ajax 调用以获取数据,并且不使用常规的 Angular $http 来执行此操作,因此使用 Angular 工具 (angular-mocks) 进行测试有点棘手。 让我们转到选项:

    1 – 使用常规 Angular 方式进行 Ajax 调用。

    Kendo 让我们改变了它获取数据的方式,所以不要这样做:

    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.:使用函数内部的变量“options”,我们可以访问 Grid 过滤器、排序和分页值。

    2 – 模拟 Kendo Ajax 调用。

    通过这种方式,我们几乎没有在 Controller 上进行任何更改,唯一需要更改的是使用 new kendo.data.DataSource({}) 创建一个新的数据源,而不仅仅是传递选项。 这需要它,因为我们在测试用例中调用了 read 函数。 我尝试了不同的方法来模拟这个 Ajax 请求,但唯一能让它工作的方法是使用一个名为 Jasmine-Ajax 的工具。 在测试用例中,我们会写如下内容:

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

    我希望这可以帮助其他人。

    【讨论】:

      猜你喜欢
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多