8

我试图将我的大脑包裹在 AngularJS 中的依赖注入上。假设这是我非常激动人心的应用程序代码:

function PrideRockCtrl($scope, King) {
  $scope.king = King;
}
  
angular.module('Characters', ['ngResource'])
  .factory('King', function() {
    return "Mufasa";
  });

我想测试PrideRockCtrl。如果我按照文档和教程中的示例进行操作,我可以使用module('Characters')来配置注入器并使用inject()来获取一些依赖项。IE:

describe('Pride Rock', function() {
  beforeEach(module('Characters'));
  it('should be ruled by Simba', inject(function($rootScope, $controller) {
    var scope = $rootScope.$new();
    var ctrl = $controller(PrideRockCtrl, {$scope: scope});
    expect(scope.king).toEqual("Mufasa");
  }));
});

这很好用,但这不是一个跨测试框架的解决方案。和测试助手只与 Jasmine 兼容module()inject()

module()在不使用or的情况下手动完成相同的依赖注入的最佳方法是什么inject()

我想出了这个:

describe('Pride Rock', function() {
  it('should be ruled by Mufasa', function() {
    var $injector = angular.injector(['Characters']);
    var $controller = $injector.get('$controller');
    var scope = $injector.get('$rootScope').$new();
    var king = $injector.get('King');
    var ctrl = $controller(PrideRockCtrl, {$scope: scope, King: king});
    expect(scope.king).toEqual("Mufasa");
  });
});

这似乎很冗长。有没有更好的办法?

jsFiddle:http: //jsfiddle.net/johnlindquist/d63Y3/

4

2 回答 2

4

不使用模块的最简单版本如下所示:

describe('Pride Rock', function() {

    it('should be ruled by Simba', inject(function($rootScope, $controller) {
        var scope = $rootScope.$new();
        var ctrl = $controller(PrideRockCtrl, {
            $scope: scope,
            King:"Mufasa"
        });
        expect(scope.king).toEqual("Mufasa");
    }));
});

事实上,您的尝试非常接近,唯一缺少的是控制器中的本地依赖项 ( King:"Mufasa")。

在像这样的测试中,我们只关注一个选定的类,没有必要使用 $injector,因为我们可以手动模拟/存根我们的依赖项。归根结底,$injector 只是提供对象的实例,因此我们也可以创建自己的对象。

于 2012-09-19T06:54:23.750 回答
4

Angular 控制器只是 JS 函数。如果你不想注入任何东西,就打电话给他们。

describe('king should be set', function() {
  var scope = {};
  var lion = "Simba";
  PrideController(scope, lion);
  expect(scope.king).toEqual(lion)
});
于 2012-11-18T02:23:37.080 回答