角度模态服务中的单元测试模板($ uibModal)

时间:2017-02-24 23:11:08

标签: angularjs unit-testing jasmine modal-dialog karma-jasmine

我有一个非常简单的service.show(),它基本上用一些配置调用$ uibModal并返回模态实例

it('should show correct message', (done) => {
    modal = modalService.show('hello');
    modal.rendered.then(()=> {
      expect($('#message').text()).toBe('hello');
      done()
    });
  });

我想编写一个测试来验证实际模态以及它是否包含预期的消息。像这样:

rendered

expect承诺永远不会得到解决。我可以做一些解决方法,比如将$timeout包装到$timeout.flush()并执行afterEach,但不确定这是否正确,即使这样,我仍然无法进行清理({{1 }})关闭模态并准备测试另一条消息。

1 个答案:

答案 0 :(得分:1)

正确的方法是打开模态窗口查找消息并关闭它,并且当引导程序使用ngAnimate动画时,我们必须包含ngAnimateMock模块来刷新挂起的动画。

检查以下代码以获得解决方案:

var myApp = angular.module('myApp', ['ngAnimate', 'ui.bootstrap']);

myApp.factory('modalService', ['$uibModal', function($uibModal) {
  return {
    show(message) {
      return $uibModal.open({
        bindToController: true,
        controllerAs: '$ctrl',
        template: '<div id="message">{{$ctrl.message}}</div>',
        controller: [function() {
          this.message = message;
        }]
      });
    }
  }
}]);

describe('modalService service', function() {
  describe('modalService', function() {
    var modalService;
    var $rootScope;
    var $animate;

    beforeEach(function() {
      module('ngAnimateMock')
      module('uib/template/modal/window.html')
      module('myApp');
    });

    beforeEach(inject(function(_$rootScope_, _modalService_, _$animate_) {
      $rootScope = _$rootScope_;
      modalService = _modalService_;
      $animate = _$animate_;
    }));

    it('should open the dialog with the correct message', () => {
      var modal = modalService.show('hello');

      $rootScope.$digest();
      // Finish the animation.
      $animate.flush();

      expect($('#message').text()).toEqual('hello');

      // Close the dialog.
      modal.close();

      $rootScope.$digest();
      // Finish the animation.
      $animate.flush();
    });

    it('again should show the correct message', () => {
      var modal = modalService.show('new message');

      $rootScope.$digest();
      // Finish the animation.
      $animate.flush();

      expect($('#message').text()).toEqual('new message');

      // Close the dialog.
      modal.close();

      $rootScope.$digest();
      // Finish the animation.
      $animate.flush();
    });
  });
});
<body>
  <!-- because we are testing our controller and not running we don't need a controller or even a module -->
  <!-- so there is no ng-app or ng-controller in the markup -->

  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css">

  <!-- the order that these files load is critical, think twice before changing -->
  <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-mocks.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap.min.js"></script>

  <h2>Finished jasmine-unit-test</h2>

</body>