2015-01-07 65 views
3

我在Grails gsp中定義了一個Angular應用程序。 Modernizr庫包含在gsp級別。使用Modernizr進行角度單元測試

我需要在指令單元測試中使用庫。由於我沒有將Modernizr定義爲模塊,因爲它在Angular應用程序之外以及它內部使用,我如何將它注入到我的Angular單元測試中?

這裏是我的指令:

'use strict'; 

angular.module('simplify.directives').directive('img', ['$timeout', function ($timeout) { 
    return { 
     restrict: 'A', 
     link: function (elem, attrs) { 
      if (typeof Modernizr !== 'undefined' && !Modernizr.svg) { 
       $timeout(function(){ 
        elem.attr('src', attrs.src.replace('.svg', '.png')); 
       }); 
      } 
     } 
    }; 
}]); 

這裏是我的單元測試代碼:

'use strict'; 

describe('Testing SVG to PNG directive', function() { 
    var scope, 
     elem; 

    beforeEach(module('app')); 

    beforeEach(module(function($provide) { 
     $provide.service('appConstants', function(){}); 
    })); 

    beforeEach(inject(function($compile, $rootScope) { 
     elem = angular.element('<img ng-src="test-img.svg" />'); 
     scope = $rootScope; 
     $compile(elem)(scope); 
     scope.$digest(); 
    })); 

    it('Should swap svg for png image if svg is not supported', function() { 
     //force Modernizr.svg to be undefined here for purposes of the test 
     expect(elem.attr('src')).toBe('test-img.png'); 
    }); 

}); 

什麼是最好的實踐方式做到這一點?

+0

在你的指令中注入'$ window'並從'$ window.Modernizr'獲取modernizer。併爲您的測試模擬現代化器 – PSL

回答

2

您可以通過更新指令來註冊$window並從$window獲得Modernizr實例。

即: -

.directive('img', ['$timeout','$window', function ($timeout, $window) { 
    return { 
     restrict: 'E', 
     link: function (scope, elem, attrs) { 

      if (typeof $window.Modernizr !== 'undefined' && !$window.Modernizr.svg) { 
       $timeout(function(){ 
        elem.attr('src', attrs.src.replace('.svg', '.png')); 
       }); 
      } 
     } 
    }; 
}]); 

在您的測試只需要創建一個模擬的Modernizr因爲你正在使用$timeout你需要做$timeout.flush()序超時回調得到執行沖洗timeout

describe('Testing SVG to PNG directive', function() { 
    var scope, 
     elem, 
     ModernizerMock = {svg:false};// <-- use this for mocking various conditions 

    beforeEach(module('app')); 

    beforeEach(module(function($provide) { 
     $provide.service('appConstants', function(){}); 
    })); 

    beforeEach(inject(function($compile, $rootScope, $timeout, $window) { 
     elem = angular.element('<img ng-src="test-img.svg" />'); 
     scope = $rootScope; 
     $window.Modernizr = ModernizerMock; //Set the mock 
     $compile(elem)(scope); 
     scope.$digest(); 
     $timeout.flush(); //<-- Flush the timeout 
    })); 

    it('Should swap svg for png image if svg is not supported', function() { 
     //force Modernizr.svg to be undefined here for purposes of the test 
      expect(elem.attr('src')).toBe('test-img.png'); 
    }); 
}); 

Plnkr

,並您的指令都是這樣:

.directive('img', ['$window', function ($window) { 
     return { 
      restrict: 'E', 
      compile: function (elem, attrs) { 
      if (typeof $window.Modernizr !== 'undefined' && !$window.Modernizr.svg) { 
       attrs.$set('ngSrc', attrs.ngSrc.replace('.svg', '.png')); 
      } 
      } 
     }; 
}]); 

這將是更小的努力,加上沒有超時邏輯的測試。 Plnkr

+1

另一個偉大的深入答案。謝謝你連續第二天! –

+0

@HellaMedusa不客氣.. :) – PSL