2017-02-15 61 views
0

運行一個單元測試失敗,並執行以下操作:設置角單元測試多個指令[...],要求新的/分離的範圍上

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(); 
}); 

最後我想實現的是用不同的輸入多次編譯組件並查看輸出。也許我正在接近完全錯誤的問題。歡迎任何建議。

回答

1

問題在於Angular模塊是持久的。現有模塊不應在規格中修改。

可以有幾個指令具有相同的名稱(選擇器),component是指令的語法糖(請參閱this answer)。這

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

導致在每個測試中爲send-email選擇器添加一個新指令到堆棧。

因此,第二次測試會導致$compile:multidir錯誤,因爲組件具有獨立的作用域,每個具有新作用域的元素不能有多個指令。

0

從estus的答案是有道理的,但我也找到了一種替代解決方案。我還沒有閱讀它的文檔,但仍然知道它爲什麼起作用,所以如果你知道,請發表評論。

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

只有變化是模塊的依賴關係的添加空列表。這允許$編譯在每個塊中被調用。