用于检查 Angular Bootstrap 模态范围的 Jasmine 单元测试

Jasmine unit test to check the scope of an Angular Bootstrap modal

我有一个物品清单。当您单击一个项目时,它会弹出一个模式来显示该项目的数据。在列表的控制器中,有一个函数 openRecentsModal,它从 ng-repeat 列表中获取数据对象,并在函数为 运行 时在新范围内创建它。然后,新模态将该对象作为 $scope.recentsFoldersData 提供。我需要编写单元测试以确保在范围内定义了 recentsFolderData,但我尝试的所有结果都导致 "expected undefined to be defined." 我希望有人能提供帮助。

这是列表控制器中打开模式的方法:

function openRecentsModal(obj) {
  var scope = $rootScope.$new();
  scope.recentsFoldersData = obj;
  var controller = 'recentsFoldersDetailController';
  $modal.open({
    scope: scope,
    controller: controller,
    templateUrl: 'js/modal/recents/folder/recentsFoldersDetail.tpl.html'
  });
}

这是模态的控制器:

angular.module('modal.recents.folder', [])
    .controller('recentsFoldersDetailController', recentsFoldersDetailController);

  recentsFoldersDetailController.$inject = ['$scope', '$modalInstance'];
  function recentsFoldersDetailController($scope, $modalInstance) {

    $scope.close = function close() {
      $modalInstance.dismiss('close');
    };
  }

最后,这是我正在处理的单元测试(我已经排除了通过的单元测试,以及该测试不需要的辅助函数):

describe('recents folders modal controller tests', function() {
  var scope, q, modal, mockDetailController, mockListController, mockRecentService, mockFolderService, mockModalInstance, $httpBackend;

  beforeEach(module('mainApp'));

  beforeEach(inject(function($rootScope, $q, $controller, $modal, _recentService_, _folderService_, $injector) {
    q = $q;
    scope = $rootScope.$new();
    modal = $modal;
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('js/modal/recents/folder/recentsFoldersDetail.tpl.html').respond(200, '');
    mockRecentService = _recentService_;
    mockFolderService = _folderService_;
    mockModalInstance = {
      dismiss: jasmine.createSpy('modalInstance.dismiss')
    };

    mockDetailController = function() {

      return $controller('recentsFoldersDetailController', {
        '$scope': scope,
        '$modalInstance': mockModalInstance
      });
    };

    mockListController = function() {

      return $controller('recentsListFoldersController', {
        '$scope': scope,
        '$modal': modal,
        'recentService': mockRecentService,
        'folderService': mockFolderService
      });
    };
  }));

  describe('scope tests', function() {

    it('should place the data on the scope when openRecentsModal is called', function() {
      var obj = defaultSuccessfulRecentsDataResponse();
      mockListController();
      spyOn(scope, 'openRecentsModal');

      scope.openRecentsModal(obj);
      expect(scope.openRecentsModal).toHaveBeenCalledWith(obj);
      mockDetailController();
      expect(scope.recentsFoldersData).toBeDefined();
    });

  });

  /* helper functions */
  function defaultSuccessfulRecentsDataResponse() {
    return {
      id: 'id 1',
      name: 'first name',
      description: 'first description'
    };
  }

});

我能够通过对调用模态的函数进行简单更改来解决此问题

    function openRecentsModal(obj) {
      $rootScope.recentsFoldersData = obj;
      var controller = 'recentsFoldersDetailController';
      $modal.open({
        //scope: scope,
        controller: controller,
        templateUrl: 'js/modal/recents/folder/recentsFoldersDetail.tpl.html'
      });
    }

通过允许将对象放置在 $rootScope(UI-Bootstrap 模态的默认设置)上,而不是新的 $scope,测试返回一个定义的值

it('should put recents object on the scope', function() {
  mockListController();

  scope.openRecentsModal(defaultSuccessfulRecentsDataResponse());
  mockDetailController();
  expect(scope.recentsFoldersData).toBeDefined();
});