如何在指令

时间:2017-12-01 12:58:10

标签: angularjs angularjs-directive jasmine

给出以下指令:

这将加载一个带有2个按钮的简单html模板,用不同的参数调用goTo函数。

function simpleMenu() {
    return {
        scope: {
            state: '='
        },
        controller: Controller,
        controllerAs: 'vm',
    };
}

function Controller($scope, $state) {
        var vm = this;
        var options = optionsService.options;
        function goTo(state) {
            switch (state){
                case 'video':
                    return $state.go('app.video');
                case 'chat':
                    return $state.go('app.chat');
            }
        }

    }

我想做一个测试,确保在执行goTo函数时调用$ state。

我的测试使用 directiveElement 来保存已编译的角元素和 directiveScope 以获取范围那个元素:

var directiveElem, compile, scope, directiveScope, $state;
$state = {
    go: jasmine.createSpy().and.returnValue('asd')
};
beforeEach(function() {
    bard.inject('$timeout', '$state');
    inject(function($compile, $rootScope, $httpBackend, $state) {
        compile = $compile;
        scope = $rootScope.$new();
        $state =  $state;
    });
});
beforeEach(function() {
    directiveElem = getCompiledElement();
});

function getCompiledElement() {
    var element = angular.element('<simpleMenu></simpleMenu>');
    var compiledElement = compile(element)(scope);
    scope.$digest();
    directiveScope = element.isolateScope();
    //Here is where I suposedly inject the mocked $state
    directiveScope.$state = $state;
    return compiledElement;
}
it('should increment value on click of button', function () {
    var output = directiveScope.vm.goTo('video-specialties');
    expect($state.go).toHaveBeenCalled();
});

最后一个测试是返回:

  

未知的间谍被称为。

似乎$ scope在directiveScope中得到了正确的模拟值,但是当返回$ state.go执行时,它从其他地方获取$ state项,也许它是由simpleMenu()注入的?我怎么能嘲笑这个对象来窥探呢?

2 个答案:

答案 0 :(得分:0)

您需要使用_$state_代替$state作为beforeEach块的参数。

改为:

inject(function($compile, $rootScope, $httpBackend, _$state_) {

答案 1 :(得分:0)

这个问题的解决方案是,Bard.js将真实对象注入执行中,所以我的模拟被每次测试都覆盖了。允许注入模拟对象的语法是:

    beforeEach(module(function ($provide) {
        $provide.value('$state', $state);
    })