2013-03-10 48 views
19

Làm thế nào để kiểm tra một bộ điều khiển với các thuộc tính phân giải? Nó ném một lỗi: Nhà cung cấp không xác định: InitProvider, trong quá trình thử nghiệm, dễ hiểu. Làm cách nào để kiểm tra?Làm thế nào tôi có thể kiểm tra một bộ điều khiển với các thuộc tính giải quyết trong AngularJS?

Tôi sử dụng thuộc tính init trong cấu hình tuyến đường để tải dữ liệu và chuyển nó đến bộ điều khiển tại trình điều khiển để tuyến đường không thay đổi trước khi dữ liệu được tải.

$routeProvider 
    .when('/topic/:topic_id/content/:content_id', { 
     templateUrl: 'views/content.html', 
     controller: 'ContentCtrl', 
    resolve: { 
     init: ContentCtrl.init 
    } 
    }); 

Mẫu có hoàn toàn sai ở địa điểm đầu tiên không?

'use strict'; 

var ContentCtrl = ['$scope', '$location', '$routeParams', 'init', function ($scope, $location, $routeParams, init) { 

    $scope.contents = init.contents; 

    }]; 

ContentCtrl.init = ['$q', 'app_config', '$log', '$timeout', function ($q, app_config, $log, $timeout) { 

    var defer = $q.defer(); 

    $log.log("ContentCtrl loading.."); 

    $timeout(function() { 
     defer.resolve({contents: [ 
            {message: 'Hello!'} 
            ]}); 

     $log.log("ContentCtrl loaded."); 

    }, 2000); 

    return defer.promise; 
}]; 

angular.module('studentportalenApp').controller('ContentCtrl', ContentCtrl); 

Tôi muốn để đóng gói toàn bộ điều khiển bên trong .controler('ContentCtrl', function() { ... }), nhưng vẫn chưa tìm ra cách này được thực hiện một cách chính xác để làm cho init có sẵn trong cấu hình tuyến đường.

+1

Hãy thử chuyển đổi 'ContentCtrl.init' sang dịch vụ' góc cạnh' và tiêm dịch vụ đó làm phụ thuộc khi cần – charlietfl

Trả lời

8

Cuối cùng nó được giải quyết bằng cách chuyển đổi mọi thứ thành dịch vụ, theo gợi ý của charlietfl.

Ví dụ:

Route config:

//This helper injects a function with the service 
//defined in the initMethod string and returns services.prepare() 
var interceptWith = function(initMethod) { 
     return [initMethod, function(m) { 
        return m.prepare(); 
       }]; 
} 

$routeProvider   
    .when('/foobar/', { 
     templateUrl: 'foobar.html', 
     controller: 'FoobarCtrl', 
     resolve: { 
      init: interceptWith('FoobarCtrlInit') 
     } 
    }); 

Định nghĩa điều khiển foobar:

angular.module('fooApp').controller('FoobarCtrl', ['$scope', 'init', function ($scope, init) {    
      $scope.data = init.data;  
    }]) 
.service('FoobarCtrlInit', ['$q', '$timeout', function ($q, $timeout) { 

     var _prepare = function() { 

      var deferred = $q.defer(); 

      //Fake async loading of data 
      $timeout(function() { 
       deferred.resolve({data: ['A','B','C']}); 
      }, 1000); 




      return deferred.promise; 
     } 

     return { 
      prepare: _prepare 
     } 
}]); 

Để kiểm tra điều này, người ta có thể làm điều này:

'use strict'; 

describe('Controller: FoobarCtrl', function() { 

    // load the controller's module 
    beforeEach(module('fooApp')); 

    var FoobarCtrl, 
    scope; 

    // Initialize the controller and a mock scope 
    beforeEach(inject(function($controller) { 
    scope = {}; 
    CourseCtrl = $controller('FoobarCtrl', { 
     $scope: scope, 
     init: {data: ['Testdata A', 'B', 'C']} 
    }); 
    })); 

    it('should attach a list of data to the scope', function() { 
    expect(scope.data.length).toBe(3); 
    }); 
}); 
24

Chạy vào cùng một thứ ở đây. Tôi đã giải quyết nó bằng cách sử dụng cách tiếp cận ở đây: https://groups.google.com/forum/?fromgroups=#!topic/angular/LzXm-9nwkjY.

Về cơ bản, tôi đã giả lập dữ liệu thường được gửi bằng cách sử dụng một biến đơn giản và thêm nó vào bộ điều khiển trong thử nghiệm. Trong trường hợp của bạn, tôi cho rằng nó sẽ trông giống như sau:

var initData = { 
     contents: [{message: 'Hello!'}] 
}; 
$controller("ContentCtrl", { $scope: ..., init: initData }); 
+1

Đây phải là câu trả lời được chấp nhận. – jacob

1

tôi đã có lỗi tương tự trong Karma khi sử dụng quyết tâm trên $ routeProvider, tôi cố định nó bằng cách kiểm tra quyết tâm của tôi trong các thử nghiệm đơn vị cho app.js, như thế này:

describe("myApp", function() { 

    beforeEach(module('myApp')); 

    it('should resolve initial values for my Controller', inject(function($route) { 
    expect($route.routes['/'].resolve.init).toBeDefined; //or whatever test you want 
    })); 
}); 

Và sau đó tôi chỉ chế giễu giá trị trên thử nghiệm cho bộ điều khiển của tôi, như thế này bên trong mô tả cho bộ điều khiển:

//mock out the resolved values to isolate controller code 
    beforeEach(module(function($provide) { 
    $provide.value('init', function() { 
     return 'whatever data you need to mock'; 
    }); 
0

để đơn vị kiểm tra giải quyết các giá trị của một tuyến đường:

var resolveObject = $ injector.invoke ($ route.current. $$ route.resolve.testedObject);

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