【问题标题】:How to unit-test the interaction of an Angular Service with $cookies?如何对 Angular 服务与 $cookies 的交互进行单元测试?
【发布时间】:2013-12-12 18:33:20
【问题描述】:

我目前有一项服务取决于 $cookies 中设置的变量。但是,当我想对服务和 $cookies 中存储的值之间的交互进行单元测试时,服务总是在 $cookie 值的实际初始化之前初始化。

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

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

【问题讨论】:

    标签: unit-testing angularjs cookies karma-runner angularjs-service


    【解决方案1】:

    我在 JSFiddle 中创建了一个示例,希望能帮助您解决问题。

    link

    //--- 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 吗?为什么它不 $cookies: 像 $scope:scope 这样的 cookie。为什么没有 $rootScope.$new() 之类的操作?
    • 属性键是可注入组件的名称,例如“$范围”。属性值是注入的实例。在上面的例子中,我将 $cookies 注入到函数中,所以我将其用作注入的实例。这只是命名用作实例的变量的问题
    • 问题与服务有关。建议的答案针对控制器,但不针对服务。控制器相对容易实例化,因为您提供了构造函数。服务更难,因为没有容易访问的构造函数。 Angular 在提供程序中实例化它们。
    【解决方案2】:

    我发现与服务(而不是控制器)一起使用的唯一方法是在beforeEach 中设置模块期间在$cookieStore 上使用装饰器。

    anagular-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');
        });
    
    
    });
    

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 2020-06-22
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-02
      • 2010-09-07
      • 1970-01-01
      相关资源
      最近更新 更多