2015-04-29 5 views
1

Я просматриваю AngularJS PhoneCat tutorial, и, хотя приложение, кажется, ведет себя правильно, когда я нажимаю на него вручную, один из модульных тестов не работает для 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, скрипт выполнит.

Из-за чтения некоторых связанных вопросов StackOverflow кажется, что у меня может быть какая-то зависимость. Соответствующие части файла 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; 
    }); 
}]); 

Как упоминалось выше, приложение работает нормально, когда я нажимаю на него в браузере, поэтому я совершенно смущен тем, что вещи разбиваются на модульные тесты.

ответ

0

Как это часто бывает с такими ошибками, исправление довольно очевидно, когда вы его видите! В принципе, в контроллерахSpec.js есть две функции: одна для списка телефонов и одна для отдельных деталей телефона. Тесты списка телефонов работали нормально, потому что у них было beforeEach(module("phonecatApp")); до звонка в beforeEach(inject(function());

С другой стороны, с подробными тестами телефона отсутствовала эта линия. Как только я переместил строку на внешнюю функцию, тесты прошли, как ожидалось. Рабочими 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 
    }); 
}); 
+1

Вы можете иметь только один 'beforeEach (инъекционные (функция() ....' в родительском описывают блок с переменными, как это: HTTP: // jsfiddle .net/hravc0g6/1 / –

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