单元测试指令-无法强制使用假数据

Unit testing a directive - Unable to force a fake data

本文关键字:数据 指令 单元测试      更新时间:2024-05-02

我正在努力了解如何在下面的情况下对指令进行单元测试。

基本上,我试图对一个有控制器的指令进行单元测试。在加载该指令时,控制器通过服务发出http请求,该服务将一些数据再次带到控制器,然后将这些数据提供给指令视图。

根据我的理解,在下面的场景中,我应该做:

  • 一个$httpBackend,用于在完成http请求时避免异常
  • 填充伪数据,以便能够使用不同的行为对指令进行单元测试
  • 编译指令

正如你所看到的,到目前为止,我一直在尝试用假数据覆盖服务。到目前为止我做不到的事。

现在出现了一些疑问。

正如你在我的控制器中看到的。我正在为视图提供整个服务:

$scope.ItemsDataservice=项目数据服务;

是什么让我相信我推翻服务的方法应该奏效。

我的问题:

在下面的场景中,我理解我可以覆盖服务来操作数据,甚至覆盖控制器来按范围操作数据。

在这里做什么是正确的?我理解错了吗?我在混合单元测试吗?

在我当前的单元测试代码中,当我应用假数据(或不应用)时,没有任何区别:

ItemsDataservice.items=DATARESULT;

ItemsDataservice.items=null;

控制器

angular.module('app')
    .controller('ItemsCtrl', function ($scope, $log, ItemsDataservice) {
        $scope.ItemsDataservice = ItemsDataservice;
        $scope.ItemsDataservice.items = null;
        $scope.loadItems = function() {
            var items = [];
            ItemsDataservice.getItems().then(function(resp) {
                if (resp.success != 'false') {
                    for (resp.something ... ) {
                        items.push({ ... });
                    };
                    ItemsDataservice.items = items;
                };
            }, function(e) {
                $log.error('Error', e);
            });
        };
        $scope.loadItems();
    });

服务

angular.module('app')
    .service('ItemsDataservice', function ItemsDataservice($q, $http) {
        ItemsDataservice.getItems = function() {
            var d = $q.defer();
            var deffered = $q.defer();
            var url = 'http://some-url?someparameters=xxx'
            $http.get(url)
                .success(function (d) {
                    deffered.resolve(d);
                });
            return deffered.promise;
        };
        return ItemsDataservice;
    });

指令

angular.module('app')
    .directive('items', function () {
        return {
            templateUrl: '/items.html',
            restrict: 'A',
            replace: true,
            controller: 'ItemsCtrl'
        };
    });

单元测试指令

ddescribe('Directive: Items', function () {
  var element, scope, _ItemsDataservice_, requestHandler, httpBackend;
  var URL = 'http://some-url?someparameters=xxx';
  var DATARESULT = [{ ... }];
  // load the directive's module
  beforeEach(module('app'));
  beforeEach(module('Templates')); // setup in karma to get template from .html
  beforeEach(inject(function ($rootScope, ItemsDataservice) {
    httpBackend = $httpBackend;
    scope = $rootScope.$new();
    _ItemsDataservice_ = ItemsDataservice;
    requestHandler = httpBackend.when('GET', URL).respond(200, 'ok');
  }));
  afterEach(function() {
    //httpBackend.verifyNoOutstandingExpectation();
    //httpBackend.verifyNoOutstandingRequest();
  });
  it('Show "No Items available" when empty result', inject(function ($compile) {
    _ItemsDataservice_.items = null;
    element = angular.element('<div data-items></div>');
    element = $compile(element)(scope);
    scope.$digest();
    element = $(element);
    expect(element.find('.msg_noresult').length).toBe(1);
  }));
  it('Should not show "No Items available" when data available ', inject(function ($compile) {
    _ItemsDataservice_.items = DATARESULT;
    element = angular.element('<div data-items></div>');
    element = $compile(element)(scope);
    scope.$digest();
    element = $(element);
    expect(element.find('.msg_noresult').length).toBe(0);
  }));
});

我解决了这个问题。

更改此行:

element=$compile(element)(scope);

到此行:

element=$compile(element.contents())(scope);

唯一的区别是jquery方法.contents()

我还不知道为什么。但它解决了。

更新

我刚刚发现的另一件事对我来说真的很有用。您可以在httpBackend:上使用正则表达式

httpBackend.whenGET(/.*NameOfThePageXXX'.aspx.*/).respond(200, 'ok');

因此,如果您只是想避免出现异常,则无需担心使用完全相同的参数等。