javascript - 对类似于 ng-if 的 Angular Directive(指令)进行单元测试

标签 javascript angularjs unit-testing karma-jasmine

我有一个服务和一个指令打包在一起,如果不满足某些条件,它们会删除 DOM 元素。

服务对传入的字符串执行检查,如果检查失败,指令将简单地删除其附加的 DOM 元素。

这适用于 IE11、Edge、Chrome 和 FireFox。但是,我似乎无法在任何测试中复制这一点。

Working code in this JSBin

这是服务及其提供商的示例

class PermissionService {
    constructor(permissions) {
        this.permissions = permissions;
    }

    addPermissions(permissions) {
        this.permissions = this.permissions.concat(permissions);
    }

    has(permission) {
        return this.permissions.indexOf(permission) !== -1;
    }
}

class PermissionProvider {
    constructor() {
        let _permissions = [];

        this.setPermissions = (permissions) => {
            _permissions = _permissions.concat(permissions);
        };

        this.$get = () => {
            return new PermissionService(_permissions);
        }
    }
}

该指令包含如何在 Angular 模块中设置的示例。

angular.module('PermissionTest', [])
  .directive('hasPermission', ['permission', '$compile', (service, $compile) => {
    return {
      restrict: 'A',
      priority: 1,
      terminal: true,
      compile: (element, attrs) => {
        let permission = attrs.hasPermission;

        if (service.has(permission)) {
            attrs.$set('hasPermission', null);
            return (scope, element) => {
                $compile(element)(scope);
            }
        } else {
            element.remove();
        }
      }
    }
  }])
  .provider('permission', PermissionProvider)
  .config(['permissionProvider', (provider) => {
    provider.setPermissions(['yes']);
  }]);

使用该指令,我现在可以轻松地从 DOM 中删除元素

<!-- Is not removed -->
<div has-permission="yes">Is not removed</div>

<!-- Is removed -->
<div has-permission="no">Is removed</div>

我有以下测试设置,我希望能够通过,但没有。我怀疑这是由于指令重新编译本身造成的,尽管我认为这应该发生在 scope.$digest() 中。任何调试帮助都会有所帮助。

let provider;
let service;

describe('directive: has-permission', () => {
    beforeEach(module('permissionChecker', (permissionProvider) => {
        provider = permissionProvider;
        provider.setPermissions(['crm.check.r', 'crm.check.c']);
    }));

    beforeEach(inject((permission) => {
        service = permission;
    }));
});

describe('if directive is not valid', () => {
    let scope;
    let element;

    beforeEach(inject(($rootScope, $compile) => {
        scope = $rootScope.$new();

        element = `<div>
            <div has-permission="crm.not.r"></div>
            <div has-permission="crm.check.r"></div>
        </div>`;

        element = $compile(element)(scope);

        scope.$digest();
    }));

    it('should remove one child element', () => {
        let test = angular.element(element).children();
        expect(test.length).toBe(1);
    });
});

最佳答案

一如既往,在发布这个问题几分钟后,我找到了问题的解决方案。我认为我可以在与其余测试分开的 describe 中构建提供程序,这是不正确的。

我通过在第一个描述中添加以下期望来调试此问题:

describe('directive:has-permission', () => {
    // Provider set up in question

    it('should exist', inject(($injector) => {
        expect($injector.has('hasPermissionDirective')).toBe(true);
    }));
});

这次成功通过了。

然后我将相同的期望添加到以下描述闭包中,令我惊讶的是测试失败了。

为了解决这个问题,我将所有后续描述嵌套在提供程序设置中,并且所有内容都按预期工作。

describe('directive:has-permission', () => {

    // Provider setup

    describe('if directive is not valid', () => {
        // Test setup and code
    });
});

关于javascript - 对类似于 ng-if 的 Angular Directive(指令)进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46872535/

相关文章:

Javascript 验证 w3c

angularjs - JasmineReporters JUnitXmlReporter 不写入文件

javascript - 有没有办法禁用 Angular Grid 虚拟化,即 Angular 根据高度/宽度位置为网格创建 div?

javascript - 有时数据没有以 Angular 加载到 CKeditor

unit-testing - 在 FakeItEasy 中伪造一个枚举器

javascript - 维护 jQuery.clone() 元素中对原始元素的引用

javascript - 在 Javascript 或 jQuery 中更改鼠标光标

javascript - React.children.only 期望接收单个 react 元素子 Navigator

javascript - 使用 Modernizr 的单元测试代码

java - Mockito 抛出 java.lang.NoClassDefFoundError 和 java.lang.VerifyError