Running a unit test fails with following:
Error: [$compile:multidir] Multiple directives [sendEmail, sendEmail] asking for new/isolated scope on: <send-email resolve="">
My unit test set up is the following. It tries to $compile the component twice in different tests. The it blocks are identical. But adding it a second time fails.
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);
});
});
So far I have tried reseting the scope and destroying the component and any combination of these. But it does not have any effect.
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();
});
In the end what I want to achieve is to compile the component multiple times with different input and see the output. Maybe I am approaching the problem completely wrong. Any suggestions are welcome.
The problem is that Angular modules are persistent. Existing module shouldn't be modified in specs.
There can be several directives with same name (selector), and component
is a syntactic sugar for a directive (see this answer). This
beforeEach(() => {
angular
.module('app')
.component('sendEmail', sendEmail);
results in adding a new directive to the stack for send-email
selector with each test.
So this will result in $compile:multidir
error on the second test, because components have isolated scopes, and there cannot be more than one directive per element with new scope.