未知提供者:$routeParamsProvider

Unknown provider: $routeParamsProvider

我正在经历 AngularJS PhoneCat tutorial and while the application seems to behave correctly when I click through it manually, one of the unit tests are failing for step 8

使用 Karma,我得到以下控制台输出:

Chrome 42.0.2311 (Windows 7) PhoneCat controllers PhoneDetailCtrl should fetch phone detail FAILED Error: [$injector:unpr] Unknown provider: $routeParamsProvider <- $routeParams

单元测试文件 (controllersSpec.js) 的相关部分如下所示:

describe("PhoneCat controllers", function () {
    describe('PhoneDetailCtrl', function () {
        var scope, $httpBackend, ctrl;

        beforeEach(inject(function (_$httpBackend_, $rootScope, $routeParams, $controller) {        
            $httpBackend = _$httpBackend_;
            $httpBackend.expectGET('phones/xyz').respond({ name: 'phone xyz' });
            $routeParams.phoneId = 'xyz';
            scope = $rootScope.$new();
            ctrl = $controller('PhoneDetailCtrl', { $scope: scope });
        }));
    });
});

问题似乎与调用inject()的函数参数声明有关。如果我取出 $routeParams 则脚本将执行。

通过阅读一些相关的 Whosebug 问题,我似乎在某处遗漏了一个依赖项。 karma.conf.js 文件的相关部分如下所示:

module.exports = function (config) {
    config.set({
        basePath: '',
        frameworks: ['jasmine'],
        files: [
            '../lib/angular/angular.js',
            '../lib/angular/angular-mocks.js',
            '../lib/angular/angular-route.js',
            '../app/*.js',
            'unit/*.js'
        ],
        browsers: ['Chrome'],
        singleRun: false
    });
};

我的 app.js 看起来像这样:

var phonecatApp = angular.module("phonecatApp", [
    "ngRoute",
    "phonecatControllers"]);

phonecatApp.config([
    "$routeProvider", function($routeProvider) {
        $routeProvider
            .when("/phones", {
                templateUrl: "Scripts/app/partials/phone-list.html",
                controller: "PhoneListCtrl"
            })
            .when("/phones/:phoneId", {
                templateUrl: "Scripts/app/partials/phone-detail.html",
                controller: "PhoneDetailCtrl"
            })
            .otherwise({
                redirectTo: "/phones"
            });
    }
]);

而 controllers.js 看起来像这样:

var phonecatControllers = angular.module("phonecatControllers", []);

phonecatControllers.controller("PhoneDetailCtrl", ["$scope", "$routeParams", "$http", function ($scope, $routeParams, $http) {
    $http.get("api/Phones/" + $routeParams.phoneId).success(function (data) {
        $scope.phone = data;
    });
}]);

正如顶部提到的,当我在浏览器中点击它时,该应用程序似乎运行良好,所以我很困惑单元测试的问题所在。

由于经常出现此类错误,当您看到它时,修复非常明显! controllersSpec.js 中基本上有两个函数,一个用于 phone 的列表,一个用于个人 phone 的详细信息。 phone 列表测试工作正常,因为它们有 beforeEach(module("phonecatApp")); 在调用 beforeEach(inject(function ());

之前

另一方面,phone 详细测试缺少此行。一旦我将行移动到外部函数,测试就会按预期通过。 工作 controllersSpec.js 看起来像这样:

describe("PhoneCat controllers", function () {
    // This is the line that was moved.
    // It existed for PhoneListCtrl but not PhoneDetailCtrl.    
    beforeEach(module("phonecatApp"));

    describe("PhoneListCtrl", function() {
        var scope, ctrl, $httpBackend;

        beforeEach(module("phonecatApp"));

        beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
            // Setup
        }));
        // Various tests
    });

    describe('PhoneDetailCtrl', function () {
        var scope, $httpBackend, ctrl;

        beforeEach(inject(function (_$httpBackend_, $rootScope, $routeParams, $controller) {
            // Setup
        }));

        // Various tests
    });
});