在单元测试中模拟$ mdSideNav

时间:2016-04-07 14:22:48

标签: angularjs jasmine angular-material

我有一个足够简单的函数来关闭我的应用程序中的$ mdSidenav实例

compile project(':GradleProjectA')

我现在需要对此进行单元测试,但是在编写对$ mdSidenav function closeSideNav() { $mdSidenav('left').close(); } 调用的期望时遇到了问题。

我考虑过在我的测试规范中使用$ provide

close()

这引发了一些错误:

  

错误:close()方法不存在

     

错误:期待间谍,但未定义。

有没有人设法嘲笑$ mdSidenav并请我提供一些指导?

由于

更新

根据建议的答案,我现在已将测试规范更新为

module(function($provide) {
    $provide.value('$mdSidenav', function(id) {
        return {
            close: jasmine.createSpy('$mdSidenav.close')
        }
    })
});

beforeEach(inject(function(_$controller_, _$mdSidenav_) {
    $controller = _$controller_;
    $mdSidenav = _$mdSidenav_;
}));

beforeEach(function() {
    vm = $controller('NavbarController', {
        $mdSidenav: $mdSidenav
    });
});

describe('vm.closeSideNav', function() {
    beforeEach(function() {
        spyOn($mdSidenav, 'close');
        vm.closeSideNav()
    });
    it('should call $mdSidenav.close()', function() {
        expect($mdSidenav.close).toHaveBeenCalled();
    });
});

对于健全性检查,我的实际控制器如下所示:

'use strict';
describe('NavbarController', function() {
  var $controller,
    vm,
    $mdSidenav,
    sideNavCloseMock;
  beforeEach(function() {
    module('app.layout');
    sideNavCloseMock = jasmine.createSpy();
    module(function($provide) {
      $provide.value('$mdSidenav', function() {
        return function(sideNavId) {
          return {close: sideNavCloseMock}
        }
      })
    });

  });
  beforeEach(inject(function(_$controller_, _$mdSidenav_) {
    $controller = _$controller_;
    $mdSidenav = _$mdSidenav_;
  }));

  beforeEach(function() {
    vm = $controller('NavbarController', {
      $mdSidenav: $mdSidenav
    });
  });
  describe('vm.closeSideNav', function() {
    beforeEach(function() {
      vm.closeSideNav()
    });
    it('should call $mdSidenav.close()', function() {
      expect(sideNavCloseMock).toHaveBeenCalled();
    });
  });
});

不幸的是,这仍然不适合我,我最终得到了一个不同的错误

(function () {
  'use strict';

  angular
    .module('app.layout')
    .controller('NavbarController', Controller);

  Controller.$inject = ['$mdSidenav'];

  function Controller($mdSidenav) {
    var vm = this;
    vm.closeSideNav = closeSideNav;

    //This only affects the sideNav when its not locked into position, so only on small\medium screens
    function closeSideNav() {
      $mdSidenav('left').close();
    }
  }
})();

1 个答案:

答案 0 :(得分:4)

close方法不属于$ mdSidenav。 $ mdSidenav是一个返回侧面导航对象的函数。这就是为什么抱怨&close()方法不存在'。

你可以做的是模仿$ mdSidenav返回一个对象帽子已经模拟了close方法,如下所示: -

var sideNavCloseMock;
beforeEach(module(function($provide){
    sideNavCloseMock = jasmine.createSpy();
    $provide.factory('$mdSidenav', function() {
        return function(sideNavId){
            return {close: sideNavCloseMock};
        };
    });
}));

然后做

it('should call $mdSidenav.close()', function() {
    expect(sideNavCloseMock).toHaveBeenCalled();
});