2015-12-22 165 views
1

如何單元測試這條使$ http調用出去的指令爲MyService?我如何正確模擬或偵察MyService單元測試使用注入服務的角度指令

angular.module('example') 
    .directive('myDirective', ['MyService', function(MyService) { 
     return { 
     restrict: 'E', 
     replace: true, 
     templateUrl: 'templates/myDirective.html', 
     scope: { 
      name: '@', 
      required: '=' 
     }, 
     link: function(scope, el, attrs, billingCtrl) { 
      scope.data = []; 

      MyService.get() 
      .then(function(res) { 
       scope.data = res; 
      }); 
     } 
     }; 
    }]); 

我的測試:

describe('Directive: <my-directive>', function() { 
    // setup code 
    beforeEach(module('example')); 

    var element; 
    var compile; 
    var scope; 
    var compiledElementScope; 
    var validTemplate = '<my-directive ng-model="testModel" name="test"></my-directive>'; 
    var MyService = { get: function() {} }; 
    var $q; 

    function getCompiledElement(template) { 
     var compiledElement; 

     compiledElement = compile(template || validTemplate)(scope); 
     scope.$digest(); 

     return compiledElement; 
    } 

    beforeEach(function() { 
     module(function($provide) { 
     $provide.value('MyService', MyService); 
     }); 

     inject(function($compile, $rootScope, _$q_) { 
     compile = $compile; 
     scope = $rootScope.$new(); 
     $q = _$q_; 
     }); 

    }); 

    describe('my directive', function() { 
     var element; 

     beforeEach(function() { 
     element = getCompiledElement(validTemplate); 
     }); 

     it('should make a call to MyService and update scope.data', function() { 
     // how do I asset the following 
     expect(scope.data).toEqual(...); 
     }); 
    }) 
    }); 

回答

1

而不是寫var MyService = { get: function() {} };創建您應用的模擬服務提供商的beforeEach內部間諜的對象。

像這樣的東西應該工作: var MyService;

beforeEach(function() { 
    MyService = jasmine.createSpyObj('MyService', ['get']); 

    MyService.get = jasmine.createSpy('get').and.callFake(function() { 
     return { 
      then: function (callback) { 
       callback(<RETURN_DATA>); 
       return this; 
      } 
     }; 
    }); 

    module(function($provide) { 
    $provide.value('MyService', MyService); 
    }); 

    ... 

}); 

對於<RETURN_DATA>只是返回你期望被保存到scope.data模擬結果。

0

您必須使用ng-mock的$ httpBackend服務。

該服務允許您預期發出http請求並模擬響應。

如果未提出請求,則測試失敗。

$ httpBackend.when ...這表示如果發出http請求,則按如下方式進行響應......沒有期望,因此如果未發出請求,則測試不會失敗。

$ httpBackend.flush()表示立即發出任何掛起的請求。如果沒有待處理的請求,它將失敗。

不要忘記......

afterEach(function() { 
    httpBackend.verifyNoOutstandingExpectation(); 
    httpBackend.verifyNoOutstandingRequest(); 
}); 

最後,$ httpBackend如果請求HTML文件的動態進行會抱怨。爲了避免這種情況的預負荷在karma.conf.js所有HTML文件

preprocessors: { 
     'src/**/!(*spec)*.js': ['coverage'], 
     'dest/**/*.html': ['ng-html2js'] 
    }, 
    ngHtml2JsPreprocessor: { 
     stripPrefix: 'dest/', 
     moduleName: 'ngHtmlFiles' 
    }, 
    coverageReporter: { 
     type: 'html', 
     dir: 'coverage' 
    }, 
    files: [ 
     'dest/vendor.min.js', 
     'bower_components/angular-mocks/angular-mocks.js', 
     'src/**/*.js', 
     'dest/**/*.html' 
    ] 

我知道這個配置的設置是一個痛苦,但如果你想跟隨行業慣例,那麼你需要得到這個工作:)