角度单位测试多个指令[...]要求新的/隔离的范围

时间:2017-02-15 16:31:30

标签: angularjs unit-testing angularjs-components

运行单元测试失败,如下所示:

Error: [$compile:multidir] Multiple directives [sendEmail, sendEmail] asking for new/isolated scope on: <send-email resolve="">

我的单元测试设置如下。它尝试在不同的测试中两次$编译组件。它的块是相同的。但是第二次添加它失败了。

import angular from 'angular';
import 'angular-mocks';
import {sendEmail} from './send-email.js';

describe('component - sendEmail', () => {
    let $rootScope;
    let $compile;
    beforeEach(() => {
        angular
            .module('app')
            .component('sendEmail', sendEmail);
        angular.mock.module('app');

        inject(function(_$rootScope_, _$compile_) {
            $rootScope = _$rootScope_;
            $compile = _$compile_;
        });
    });

    it('...', () => {
        const element = $compile('<send-email resolve=""></send-email>')($rootScope);
        $rootScope.$digest();
        expect(element.find('.hp-send-email-container').length).toEqual(1);
    });

    // adding it will fail the test
    it('...', () => {
        const element = $compile('<send-email resolve=""></send-email>')($rootScope);
        $rootScope.$digest();
        expect(element.find('.hp-send-email-container').length).toEqual(1);
    });
});

到目前为止,我已经尝试重新调整范围并销毁组件及其组合。但它没有任何影响。

it('...', () => {
    // tried creating and using a new scope for $compile
    // const $scope = $rootScope.$new(true);
    const element = $compile('<send-email resolve=""></send-email>')($rootScope);
    $rootScope.$digest();
    expect(element.find('.hp-send-email-container').length).toEqual(1);

    // tried removing the element as well as destroying the scope
    // element.remove();
    // $scope.$destroy();
});

最后我想要实现的是使用不同的输入多次编译组件并查看输出。也许我正在接近完全错误的问题。欢迎任何建议。

2 个答案:

答案 0 :(得分:1)

问题是Angular模块是持久的。不应在规范中修改现有模块。

可以有几个具有相同名称(指示符)的指令,component是指令的语法糖(请参阅this answer)。此

beforeEach(() => {
    angular
        .module('app')
        .component('sendEmail', sendEmail);

导致在每次测试时为send-email选择器添加一个新指令。

因此,这将导致第二次测试出现$compile:multidir错误,因为组件具有隔离范围,并且每个具有新范围的元素不能有多个指令。

答案 1 :(得分:0)

来自estus的答案是有道理的,但我也找到了另一种解决方案。我还没有读过它的文档但还不知道它为什么有效,所以如果你知道,请发表评论。

angular
   .module('app', [])
   .component('sendEmail', sendEmail);
angular.mock.module('app');

只有更改是添加到模块的依赖项的空列表。这允许在每个块中调用$ compile。