$ timeout,在angular directive test和$ httpBackend模拟错误中触发app初始化

时间:2014-07-05 16:12:08

标签: angularjs unit-testing angularjs-directive

我遇到了测试问题(Karma + Mocha + Chai)。我正在测试一个非常简单的指令,它是更大的角度模块(webapp)的一部分。问题是,在我的测试中调用$timeout.flush()时,模块/ app get初始化并发出请求以获取主页的模板。由于$httpBackend(ng-mock的一部分)不期望任何请求失败:

Unexpected request: GET /partials/homepage
No more request expected
$httpBackend@/Users/doup/Sites/projects/visitaste-web/bower_components/angular-mocks/angular-mocks.js:1208:1
...
continues

指令如何触发模块初始化?任何想法如何避免这个问题?最好不要将此代码切换到另一个模块中。

谢谢!


这里是指令:

module.exports = ['$timeout', function ($timeout) {
    return {
        restrict: 'A', // only for attribute names
        link: function ($scope, element, attrs) {
            $scope.$on('vtFocus', function (event, id) {
                if (id === attrs.vtFocus) {
                    $timeout(function () {
                        element.focus();
                    }, 0, false);
                }
            });
        }
    };
}];

这里是实际测试:

describe('vtFocus', function() {
    var $scope, $timeout, element;

    beforeEach(module('visitaste'));

    beforeEach(inject(function ($injector, $compile, $rootScope) {
        $scope   = $rootScope.$new();
        $timeout = $injector.get('$timeout');
        element  = angular.element('<input vt-focus="my-focus-id"/>');

        $compile(element)($scope);
    }));

    it('should focus the element when a vtFocus event is broadcasted with the correct focus ID', function () {
        expect(element.is(':focus')).to.be.false;
        $scope.$broadcast('vtFocus', 'my-focus-id');
        $timeout.flush();
        expect(element.is(':focus')).to.be.true;
    });

    it('should NOT focus the element when a vtFocus event is broadcasted with a different focus ID', function () {
        expect(element.is(':focus')).to.be.false;
        $scope.$broadcast('vtFocus', 'wrong-id');
        $timeout.flush();
        expect(element.is(':focus')).to.be.false;
    });

});

这是我在/中为路径app.config()配置UI路由器的部分:

// ...

$stateProvider
.state('homepage', {
    url: '/',
    templateUrl: '/partials/homepage',
});

// ...

1 个答案:

答案 0 :(得分:1)

作为一种解决方法,我只是将指令移动到它自己的模块visitaste.directives中并在测试中加载了该模块,所以现在它已经从UI-Router中分离出来并且它没有&#39 ; t触发对模板的请求。

在我接受这个答案之前,我仍然会等待另一个解决方案。

describe('vtFocus', function() {
    var $scope, $timeout, element;

    beforeEach(module('visitaste.directives'));

    beforeEach(inject(function ($compile, $rootScope, _$timeout_) {
        $scope   = $rootScope.$new();
        $timeout = _$timeout_;
        element  = angular.element('<input vt-focus="my-focus-id"/>');
        element.appendTo(document.body);

        $compile(element)($scope);
    }));

    afterEach(function () {
        element.remove();
    });

    it('should focus the element when a vtFocus event is broadcasted with the correct focus ID', function () {
        expect(document.activeElement === element[0]).to.be.false;
        $scope.$broadcast('vtFocus', 'my-focus-id');
        $timeout.flush();
        expect(document.activeElement === element[0]).to.be.true;
    });

    it('should NOT focus the element when a vtFocus event is broadcasted with a different focus ID', function () {
        expect(document.activeElement === element[0]).to.be.false;
        $scope.$broadcast('vtFocus', 'wrong-id');
        expect(document.activeElement === element[0]).to.be.false;
    });

});