2015-12-22 133 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' 
    ] 

我知道这个配置的设置是一个痛苦,但如果你想跟随行业惯例,那么你需要得到这个工作:)