Угловой юнит-тест Множество директив [...], требующих новую / изолированную область

Запуск модульного теста завершается неудачно с помощью следующего:

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

Мой юнит тест настроен следующим образом. Он пытается дважды скомпилировать компонент в разных тестах. Блоки it идентичны. Но добавить его во второй раз не удается.

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 ответа

Решение

Проблема в том, что угловые модули постоянны. Существующий модуль не должен быть изменен в спецификации.

Может быть несколько директив с одним и тем же именем (селектором), и component является синтаксическим сахаром для директивы (см. этот ответ). это

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

приводит к добавлению новой директивы в стек для send-email селектор с каждым тестом.

Так что это приведет к $compile:multidir ошибка во втором тесте, потому что компоненты имеют изолированные области, и не может быть более одной директивы на элемент с новой областью действия.

Ответ от Estus имеет смысл, но я также нашел альтернативное решение. Я еще не читал эту документацию, чтобы знать, почему она работает, поэтому, если вы знаете, оставьте комментарий.

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

Единственное изменение - добавлен пустой список зависимостей в модуль. Это позволяет вызывать $compile в каждом блоке it.

Другие вопросы по тегам