2015-02-05 71 views
0

我正在測試使用隔離範圍的下面的指令。我知道triggerHandler正在工作,但由於某種原因,我不斷收到錯誤element.click指令單元測試沒有賦值給變量

預計未定義爲'http://www.gravatar.com/avatar/12345?s=40&d=identicon'。

指令:

angular.module('pb.webSites.directives') 
    .directive('pbOrganizationImagePicker', [ function() { 

     return { 
      restrict: "E", 
      template: '<img data-ng-src="{{ imageSource }}" width="{{width}}" height="{{height}}" alt="Image Picker" class="img-rounded" />', 
      scope: { 
       fileId: '=pbFileId', 
       defaultSrc: '@pbDefaultSrc', 
       width: '@pbWidth', 
       height: '@pbHeight' 
      }, 
      controller: 'pbOrganizationImagePickerController', 

      link: function (scope, element, attrs) { 
       scope.$watch('defaultSrc', function (value) { 
        if (value !== undefined) { 
         scope.imageSource = value; 
        } 
       }); 

       element.on('click', function() { 
        scope.pickImage().then(function (image) { 
         scope.imageSource = image.storageUrl; 
         scope.fileId = image.fileId; 
        }, function() { 
         console.log('Modal dismissed at: ' + new Date()); 
        }); 
       }); 
      } 
     }; 
    }]); 

測試:

describe('pbOrganizationImagePicker', function() { 

    beforeEach(module('pb.webSites.controllers')); 
    beforeEach(module('pb.webSites.directives')); 
    beforeEach(module('ui.router')); 
    beforeEach(module('ui.bootstrap')); 

    var compile; 
    var scope; 
    var mockModal = {}; 
    var image; 

    beforeEach(inject(function ($compile, $rootScope) { 
     compile = $compile 
     scope = $rootScope.$new(); 
    })); 


    beforeEach(inject(function ($q, $injector) { 

     $httpBackend = $injector.get('$httpBackend'); 
     $httpBackend.whenGET('/app/webSites/directives/OrganizationImagePicker.html').respond(200, ''); 

     scopeObject = { 
      profileImageUrl: 'http://www.gravatar.com/avatar/12345?s=40&d=identicon', 
      profileImageId: 54634 
     }; 

     scope.webSite = { 
      profileImageId: 6436 
     }; 

     scope.pickImage = function() { 
      var defer = $q.defer(); 
      defer.resolve(scopeObject); 
      return defer.promise; 
     }; 

    })); 

describe('element.click()', function() { 

     beforeEach(function() { 
      var html = angular.element('<pb-organization-image-picker data-pb-default-src="{{ webSite.profileImageUrl || \'/content/img/placeholder-lg.jpg\' }}" data-pb-file-id="webSite.profileImageId" data-pb-width="200"></pb-organization-image-picker>'); 
      element = compile(html)(scope); 
      element.triggerHandler('click'); 
     }); 

     it('should assign value to scope variables', function() { 
      scope.pickImage(); 
      scope.$digest(); 
      expect(scope.imageSource).toEqual(scopeObject.profileImageUrl); 
      expect(scope.fileId).toEqual(scopeObject.profileImageId); 
     }); 

    }); 

});

我也嘗試改變測試以下,因爲我非常確定在上面的測試我僞裝測試了一下。然而在這裏,我從來沒有調用pickImage()。即使您沒有看到問題,您認爲哪種方法更適合測試?

describe('element.click()', function() { 


     it('should assign value to scope variables', function() { 
      element = compile(html)(scope); 
      spyOn(scope, 'pickImage'); 
      element.triggerHandler('click'); 
      scope.$apply(); 
      //scope.pickImage(); 
      expect(scope.pickImage).toHaveBeenCalled(); 
      scope.$digest(); 
      expect(scope.imageSource).toEqual(scopeObject.profileImageUrl); 
      expect(scope.fileId).toEqual(scopeObject.profileImageId); 
     }); 

    }); 

回答

0
element.on('click', function() { 
    scope.$apply(function() { 
     scope.pickImage().then(function (image) { 
      scope.imageSource = image.storageUrl; 
      scope.fileId = image.fileId; 
     }, function() { 
      console.log('Modal dismissed at: ' + new Date()); 
     }); 
    }); 
}); 

裹的代碼在點擊處理程序在$適用。我懷疑真正的問題是你的指令使用隔離作用域,所以它實際上不會有一個「pickImage()」方法,當你指定imageSource和fileId時,你將它們放在指令作用域上,並且而不是您的測試試圖驗證的範圍(父範圍)。

您的測試將pickImage()和webSite分配給您的測試元素的範圍。由於您使用的是獨立範圍,因此您的指令無法訪問這些方法和屬性。您應該將這些移動到一個服務中,並將它們注入到指令中。

這不是「正確的」,但測試您可以將指令更改爲理論:

element.on('click', function() { 
    scope.$apply(function(){ 
     scope.$parent.pickImage().then(function (image) { 
      scope.$parent.imageSource = image.storageUrl; 
      scope.$parent.fileId = image.fileId; 
     }, function() { 
      console.log('Modal dismissed at: ' + new Date()); 
     }); 
    }); 
}); 

這是不是你在生產代碼想要的東西,但我只是想演示如何不同範圍是相互關聯的。

+0

好的想法,但仍然沒有運氣 – ReganPerkins

+0

它仍然需要在那裏(爲你的野生代碼)。測試可能會起作用,因爲您在測試中手動調用scope.digest()。 –

+0

相關提示!感謝喬 – ReganPerkins