如何对Angular服务与$cookies进行单元测试?

5

我目前有一个依赖于$cookies中设置的变量的服务。但是,在我想要单元测试服务和$cookies中存储的值之间的交互时,服务始终在实际初始化$cookie值之前被初始化。

所以,我的问题是:如何正确地对服务和$cookie值进行单元测试?(例如:如何在我的服务初始化之前设置$cookies中的值?)

注意:我正在使用Angular 1.2和Karma进行单元测试。

2个回答

6
我在JSFiddle中创建了一个示例,希望它能帮助你解决问题。 链接
//--- CODE --------------------------
angular.module('myapp.test', [], function () {

}).controller('testcont', function($scope, $cookies) {
    // Read a cookie and do something with it
    $scope.favoriteCookie = $cookies.myFavorite;
});

// --- SPECS -------------------------

describe('controllers', function(){
  var scope;   
  beforeEach(angular.mock.module('ngCookies', 'myapp.test'));   
  beforeEach(inject(function($controller, $rootScope, $cookies){    
    // Setting a cookie for testing
    $cookies.myFavorite = 'oatmeal';
    scope = $rootScope.$new();
      $controller('testcont', {$scope:scope, $cookies: $cookies});
  }));

  it('sets the cookie on the scope', function(){
      expect(scope.favoriteCookie).toBe('oatmeal');      
  });
});

你好,你能解释一下为什么要使用 $cookies: $cookies 吗?为什么它不是像 $scope:scope 那样的 $cookies: cookies 呢?为什么没有像操作那样的 $rootScope.$new() 呢? - user4232
属性键是可注入组件的名称,例如"$scope"。属性值是被注入的实例。在上述情况中,我将$cookies注入到函数中,所以我将其用作注入的实例。只需将用作实例的变量命名即可。 - Eitan Peer
1
问题涉及服务。提出的答案解决了控制器,但没有解决服务。控制器相对容易实例化,因为您可以提供构造函数。服务更难,因为没有易于访问的构造函数。Angular在提供程序内部实例化它们。 - Gil Elad

2

我发现,对于服务(而不是控制器),唯一可行的方法是在 beforeEach 中使用 $cookieStore 的修饰器来设置模块。

angular-mocks 让我们可以在规范中以与代码相似的方式配置我们的模块,除了不使用 config 函数之外,我们将一个函数作为第二个参数传递给 module 函数,用于在 jasmine 中调用我们的模块。

它看起来像这样:

describe ('my service', function () {
    var $cookieStore,
        myService

    beforeEach(module ('myModule', function ($provide) {
        // this function configures the "myModule" module before any
        // injectables are created.

        // We use a decorator to access the cookie store before other
        // services are instantiated.
        $provide.decorator ('$cookieStore', function ($delegate) {
            // at this point the "$cookieStore" service  has only just 
            // been constructed, and is accessible here as "$delegate".
            // Services that have "$cookieStore" as an injected
            // dependency have not been instantiated yet, so we
            // can slip our cookie in now.
            $delegate.put ('favorite-cookie', 'oatmeal');
            return $delegate;
        });
    }));

    beforeEach (inject (function (_$cookieStore_, _myService_) {
        myService = _myService;
        $cookieStore = _$cookieStore_;
    }

    it ('should interact with the pre-existing "favorite-cookie" cookie', function () {
        // your expectations go here.
    });

    afterEach(function() {
        // clean up
        $cookieStore.remove ('favorite-cookie');
    });


});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接