单元测试自定义提供程序

时间:2016-07-19 15:18:53

标签: angularjs unit-testing karma-jasmine

我们如何测试$ get in customer provider中的条件,我想测试showSpinner下的else条件。

我将使用

在配置中启用我的spinnerSerive
spinnerService.showSpinner(true) or spinnerService.showSpinner(false)



  angular.module('providerModule', []).provider('spinnerService', [
  function() {
    var enabled = true;
    return {
      spinnerEnabled: function(setting) {
        if (angular.isDefined(setting)) {
          enabled = setting;
          return this;
        } else {
          return enabled;
        }
      },
      $get: function($injector) {
        return {
          showSpinner: function(option) {
            if (enabled) {
              if(option){
                  angular.element(document.body).append('<div id="spinner"><div class="modal-backdrop fade in"></div><div class="load5"><div class="loader" ></div></div></div>');
                }
              else{
                angular.element(document.querySelector('#spinner')).remove();

              }
            }
          }
        }
      }
    }

  }
]);

使用

在控制器中切换我的微调器
    describe('Spinner Provider', function(){
    var spinnerServiceObj;
    beforeEach(module('providerModule'));
    describe('testing spinner', function(){
        beforeEach(function() {
            inject(function(_spinnerService_,_$rootScope_) {
                spinnerServiceObj = _spinnerService_;
                $rootScope = _$rootScope_;
                $rootScope.showSpinner = jasmine.createSpy(spinnerServiceObj.showSpinner(true))
            });
        });
        it('Should test showSpinner with true and false', function() {
            expect($rootScope.showSpinner ).toHaveBeenCalled();

        });
    })
})

我能够测试是否已经调用了showSpinner但是如何测试它是否正确输入if和else。以下是spec.js

{{1}}

2 个答案:

答案 0 :(得分:0)

在描述块内,使用:

beforeEach(function() {
  module('providerModule')
    .config(function(spinnerServiceProvider) {
       // set enabled/disabled here 
    });
});

这应该允许您测试任一条件。

答案 1 :(得分:0)

单元测试不应该针对真实DOM进行测试,特别是如果这可能会给测试运行器带来问题。

直接document引用应替换为$window.document$windowto make mocking the globals easier

然后可以用

进行模拟
var bodyMock = {};

beforeEach(module('providerModule', { $window: {
  document: {
    body: bodyMock,
    querySelector: jasmine.createSpy()
  }
} }));

angular.element或jQuery可以通过完全模拟或仅prototype methods进行测试:

// angular.element.prototype should be stubbed before angular.element
// because a spy doesn't expose original `prototype`
spyOn(angular.element.prototype, 'append');
spyOn(angular.element.prototype, 'remove');
spyOn(angular, 'element').and.callThrough();

可以使用

测试一个条件
spinnerService.showSpinner(true);

expect(angular.element).toHaveBeenCalled();
expect(angular.element.calls.mostRecent().args[0]).toBe(bodyMock);
expect(angular.element.prototype.append).toHaveBeenCalledWith('<div...);
expect($window.document.querySelector).not.toHaveBeenCalled();

可以使用

测试另一个条件
var spinnerMock = {};
$window.document.querySelector.and.returnValue(spinnerMock);

spyOn(angular, 'element').and.callThrough();

spinnerService.showSpinner();

expect($window.document.querySelector).toHaveBeenCalled('#spinner');

expect(angular.element).toHaveBeenCalled();
expect(angular.element.calls.mostRecent().args[0]).toBe(spinnerMock);
expect(angular.element.prototype.remove).toHaveBeenCalled();
expect(angular.element.prototype.append).not.toHaveBeenCalled();

或者,可以单独模拟$window.document以对某个分离的DOM元素进行操作,因此可以针对元素内容测试showSpinner调用的结果。