Jason
Jason

Reputation: 11363

Angular and Karma - Why does this test fail?

I'm working on the Angular Phonecat tutorial, and incorporating some of the suggestions in Opinionated AngularJS Styleguide

However, I'm having a hard time understanding why a specific Karma test is failing.

My application code is:

function routeProvider(provider){ ... }

function phoneListCtrl(scope, http){ ... }

function phoneDetailCtrl(scope, http, routeParams){
    http.get("/phones/" + routeParams.phoneId + ".json").success(function(data){
        scope.phone = data;
    });
}

angular.module("phonecatApp", ["ngRoute"])
    .controller('PhoneListCtrl', ["$scope", "$http",  function($scope, $http){
         phoneListCtrl($scope, $http);
    }])
    .controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$http', function($scope,     $routeParams, $http){
        phoneDetailCtrl($scope, $http, $routeParams);
    }])
    .config(['$routeProvider',function($routeProvider) {
        routeProvider($routeProvider);
    }]);

This application code works in the browser, where both phone list and phone detail views show as expected. No errors are reported in the console.

However, this test for PhoneDetailCtrl fails due to

PhoneCat Controllers PhoneDetailCtrl should fetch phone detail FAILED
Error: [$injector:unpr] Unknown provider: $routeParamsProvider <- $routeParams

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

    beforeEach(inject(function(_$httpBackend_, $rootScope, $routeParams, $controller){
        $httpBackend = _$httpBackend_;
        $httpBackend.expectGET("phones/xyz.json").respond({name : "phone xyz"});

        $routeParams.phoneId = "xyz";
        scope = $rootScope.$new();
        ctrl = $controller("PhoneDetailCtrl", {$scope : scope});
    }));

    it("should fetch phone detail", function(){
        expect(scope.phone).toBeUndefined();
        $httpBackend.flush();

        expect(scope.phone).toEqual({name : "phone xyz"});
    });
});

Specifically, the beforeEach(inject(function( ... ) { ... })); is throwing the error prior before going to code in angular-mocks.js.

Why is the test code failing only after reorganizing the application code, yet still works in the browser? This only occurs when running Karma tests, all Protractor tests pass.

ETA

Some people have asked about the files array in karma.conf.js. The settings are:

files : [
  'app/bower_components/angular/angular.js',
  'app/bower_components/angular-route/angular-route.js',
  'app/bower_components/angular-mocks/angular-mocks.js',
  'app/js/**/*.js',
  'test/unit/**/*.js'
],

Upvotes: 0

Views: 1752

Answers (2)

edufinn
edufinn

Reputation: 2447

I had similar error in exactly the same test. I figured out that problem was in the fact that module was defined inside one of the internal describe blocks. Moving module creation statement to the top level describe block fixed this error.

Here's erroneous code:

'use strict';

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

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

        beforeEach(module('phonecatApp'));
        ...
    });

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

Correct should be:

'use strict';

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

    beforeEach(module('phonecatApp'));

    describe('PhoneListCtrl', function() {
        var scope, ctrl, $httpBackend;
        ...
    });

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

Upvotes: 4

Evgeny Rivkin
Evgeny Rivkin

Reputation: 1

looks like you are missing reference to bower_components/angular-route/angular-route.js in your karma.conf.js .. check this file or any other entity you use for testing that it has angular-route DI

Upvotes: 0

Related Questions