angularjs指令单元测试失败,带有controllerAs,bindToController& isolateScope()

时间:2017-05-03 20:18:52

标签: angularjs unit-testing directive isolate-scope controlleras

我正在尝试使用双向绑定属性(=)对指令进行单元测试。该指令适用于我的应用程序,但我无法通过单元测试来测试双向绑定。

我一直试图让这个工作好几天。我已经阅读了许多使用一些但不是所有我想要使用的功能的例子:controllerAs,bindToController& isolateScope()。 (忘了我还需要的templateURL。我会补充一点,如果我能让这个工作!:)

我希望有人可以告诉我如何显示隔离范围中反映的父范围的变化。

这是一个包含以下代码的plunkr:

http://plnkr.co/edit/JQl9fB5kTt1CPtZymwhI

这是我的测试应用:

var app = angular.module('myApp', []);

angular.module('myApp').controller('greetingController', greetingController);
greetingController.$inject = ['$scope'];
function greetingController($scope) {
  // this controller intentionally left blank (for testing purposes)
}

angular.module('myApp').directive('greetingDirective',
        function () {
            return {
                scope: {testprop: '='},
                restrict: 'E',
                template: '<div>Greetings!</div>',
                controller: 'greetingController',
                controllerAs: 'greetingController',
                bindToController: true
            };
        }
);

这是规范:

describe('greetingController', function () {

var ctrl, scope, rootScope, controller, data, template,
        compile, isolatedScope, element;

beforeEach(module('myApp'));

beforeEach(inject(function ($injector) {

    rootScope = $injector.get('$rootScope');
    scope = rootScope.$new();
    controller = $injector.get('$controller');
    compile = $injector.get('$compile');

    data = {
        testprop: 1
    };

    ctrl = controller('greetingController', {$scope: scope}, data);
    element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>');
    template = compile(element)(scope);
    scope.$digest();
    isolatedScope = element.isolateScope();

}));

// PASSES
it('testprop inital value should be 1', function () {
    expect(ctrl.testprop).toBe(1);
});

// FAILS: why doesn't changing this isolateScope value 
// also change the controller value for this two-way bound property?
it('testprop changed value should be 2', function () {
    isolatedScope.testprop = 2;
    expect(ctrl.testprop).toBe(2);
}); 
});

1 个答案:

答案 0 :(得分:3)

您必须更正您测试指令的方式。您直接更改了对象的isolatedScope,然后验证了您编译过的ctrl无关DOM对象。

基本上你应该做的就是编译带范围的DOM(这里是<greeting-directive testprop="testprop"></greeting-directive>)。这样,范围将保持编译的上下文。简而言之,您可以播放testprop属性值。或同样的事情将在element.scope()内提供。只要您更改scope / currentScope中的任何值。您可以在指令isolatedScope中看到值已更新。我要提及的另一件事是controllerAs bindToController: true scopeisolatedScope.greetingController.testprop {@ 1}} assert内的控制器别名添加属性describe('greetingController', function() { var ctrl, scope, rootScope, controller, data, template, compile, isolatedScope, currentScope, element; beforeEach(module('myApp')); beforeEach(inject(function($injector) { rootScope = $injector.get('$rootScope'); scope = rootScope.$new(); controller = $injector.get('$controller'); compile = $injector.get('$compile'); data = { testprop: 1 }; ctrl = controller('greetingController', { $scope: scope }, data); element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>'); template = compile(element)(scope); scope.$digest(); currentScope = element.scope(); //OR //currentScope = scope; //both are same isolatedScope = element.isolateScope(); })); // First test passes -- commented it('testprop changed value should be 2', function() { currentScope.testprop = 2; //change current element (outer) scope value currentScope.$digest(); //running digest cycle to make binding effects //assert expect(isolatedScope.greetingController.testprop).toBe(2); }); }); } set @sql = ( select group_concat(distinct concat( "(case when `Occupation`='", Occupation, "' then `Name` end) as `", `Occupation`, "`" ) ) from t ); set @sql = concat("select ", @sql, " from t "); prepare stmt from @sql; execute stmt;

<强>代码

library(dplyr)
library(ggplot2)

dat <- data_frame(group, values) %>%
    count(group, values) %>%
    group_by(group) %>%
    mutate(percent = n / sum(n),
           error = sqrt((percent * (1-percent))/n)) %>%
    mutate(values = factor(values, levels = c("low", "med", "high")))

dat

#> Source: local data frame [5 x 5]
#> Groups: group [2]
#> 
#>   group values     n   percent     error
#>   <chr> <fctr> <int>     <dbl>     <dbl>
#> 1     a   high     2 0.5000000 0.3535534
#> 2     a    low     2 0.5000000 0.3535534
#> 3     b   high     1 0.3333333 0.4714045
#> 4     b    low     1 0.3333333 0.4714045
#> 5     b    med     1 0.3333333 0.4714045


ggplot(dat, aes(values, percent, fill = group)) + 
    geom_col(position = "dodge") +
    geom_errorbar(aes(ymin = percent - error, ymax = percent + error),
                  position = position_dodge(0.9))

Demo Plunker