最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS Karma test - Resolve object passed into controller is undefined when testing - Stack Overflow

programmeradmin1浏览0评论

We are using ui-router 0.2.10.

I am injecting a resolve object as a parameter into my controller, which is then setting a scope variable in the controller. It works perfectly on the app like so:

state provider

$stateProvider.state('myState', {
      resolve:{
         foo:  function(){
            return 'bar';
         },
      url: '/',
      templateUrl: 'index.html',
      controller: 'FooCtrl'
   })

controller

app.Controllers.controller('FooCtrl', ['$scope', '$state', 'foo',
    function ($scope, $state, $log, Zone, foo) {
        $scope.testVar = foo
        console.log($scope.testVar);
    }])

'Bar' is then logged to the console as expected in Chrome.

But when running tests using Karma, the resolve object is now undefined, which fails the test. Here is the test code:

describe('controllers', function(){

  var $rootScope, 
      $scope,
      $state

  beforeEach(module('app'))

  beforeEach(inject(function($injector) {
    $state = $injector.get('$state')
    $rootScope = $injector.get('$rootScope')
    $scope = $rootScope.$new()
    $controller = $injector.get('$controller')
  }))

  it('FooCtrl should exist', inject( function() {
    $state.go('myState')
    $rootScope.$apply()

    $controller = $controller('FooCtrl', {
      '$scope': $scope
    })
    $rootScope.$apply()

    assert.equal($scope.testVar, "bar", "these strings are equal")
  }))
})

This error is presented (the resolve object in my case is called resolvedRouteModels):

[$injector:unpr] Unknown provider: fooProvider <- foo
    .3.0-build.2921+sha.02c0ed2/$injector/unpr?p0=fooProvider%20%3C-%20foo

Any help would be much appreciated, and please let me know if you have encountered this problem.

We are using ui-router 0.2.10.

I am injecting a resolve object as a parameter into my controller, which is then setting a scope variable in the controller. It works perfectly on the app like so:

state provider

$stateProvider.state('myState', {
      resolve:{
         foo:  function(){
            return 'bar';
         },
      url: '/',
      templateUrl: 'index.html',
      controller: 'FooCtrl'
   })

controller

app.Controllers.controller('FooCtrl', ['$scope', '$state', 'foo',
    function ($scope, $state, $log, Zone, foo) {
        $scope.testVar = foo
        console.log($scope.testVar);
    }])

'Bar' is then logged to the console as expected in Chrome.

But when running tests using Karma, the resolve object is now undefined, which fails the test. Here is the test code:

describe('controllers', function(){

  var $rootScope, 
      $scope,
      $state

  beforeEach(module('app'))

  beforeEach(inject(function($injector) {
    $state = $injector.get('$state')
    $rootScope = $injector.get('$rootScope')
    $scope = $rootScope.$new()
    $controller = $injector.get('$controller')
  }))

  it('FooCtrl should exist', inject( function() {
    $state.go('myState')
    $rootScope.$apply()

    $controller = $controller('FooCtrl', {
      '$scope': $scope
    })
    $rootScope.$apply()

    assert.equal($scope.testVar, "bar", "these strings are equal")
  }))
})

This error is presented (the resolve object in my case is called resolvedRouteModels):

[$injector:unpr] Unknown provider: fooProvider <- foo
    http://errors.angularjs/1.3.0-build.2921+sha.02c0ed2/$injector/unpr?p0=fooProvider%20%3C-%20foo

Any help would be much appreciated, and please let me know if you have encountered this problem.

Share Improve this question asked Jul 15, 2014 at 23:28 andrewandrew 2551 gold badge4 silver badges8 bronze badges 1
  • stackoverflow./questions/17567894/… – maurycy Commented Jul 15, 2014 at 23:35
Add a ment  | 

2 Answers 2

Reset to default 11

When you instantiate your controller, Angular usually can figure out how to satisfy the controller's dependencies. In this case, it doesn't know about UI-Router's "resolve" functionality.

One way to address this is to supply this dependency yourself in the test, the same way you are passing in the scope to the controller:

var foo = 'bar'; // whatever
$controller = $controller('FooCtrl', {$scope: $scope, foo: foo} );

Note, you could also create a mock $state object and pass that into the controller the same way, if you wanted to incorporate that into your tests.

my assumption is your Angular set up is perfect, if that's the case, you might want to test your code this way. I've used Jasmine 2 syntax.

describe('Foo Controller', function() {
    var  $scope, $state, controller, Zone, foo, $log;
    beforeEach(module('app'));

    beforeEach(inject(function($controller) {
        $scope = {};
        $state = {};
        $log = {};
        Zone = {};
        foo = {};
        controller = $controller;
    }));

    it('should log the value foo', function() {
        spyOn(console, 'log');
        controller('FooCtrl', { $scope, $state, $log, Zone, foo });
        expect($scope.testVar).toEqual({});
        expect(console.log).toHaveBeenCalledWith({});
    });

    it('should log the value foo', function() {
        spyOn(console, 'log');
        // You could change the value of foo i.e.
        foo = 'create more spies than fbi';
        controller('FooCtrl', { $scope, $state, $log, Zone, foo });
        expect($scope.testVar).toEqual('create more spies than fbi');
        expect(console.log).toHaveBeenCalledWith('create more spies than fbi');
    });

});

Once again I hope this helps. Peace.

发布评论

评论列表(0)

  1. 暂无评论