2014-08-28 40 views
2

我的指令在瀏覽器中正常運行。這只是單元測試,我似乎無法工作。該指令創建一個簡單的滑塊,並在範圍上設置一些值,包括min

在單元測試中,$ compile(element)似乎只是將它包裝在jqlite中,而沒有對它做任何事情。好吧,它也顯然給了它一個範圍,但範圍上沒有任何東西。該模板還沒有被應用。

我的單元測試:

describe('Given the slider directive', function() { 

beforeEach(function() { 
    module('app'); 
}); 

beforeEach(inject(function($httpBackend){ 
    // necessary because .whenGET().passThrough() doesn't seem to work 
    $httpBackend.whenGET('partials/slider.html').respond('<div class="slider horizontal">'+ 
     '<div class="min">{{min}}</div>'+ 
     '<div class="max">{{max}}</div>'+ 
     '<a slider-handle class="handle" ng-class="{focus: focus}"'+ 
     'role="slider"'+ 
     'aria-valuemin="{{min}}" aria-valuemax="{{max}}" aria-valuenow="{{slider.value}}" aria-labelledby="{{id}}-label" aria-controls="{{id}}-value"'+ 
     'tabindex="0"'+ 
     'ng-keydown="handleKeyDown($event)" ng-keypress="handleKeyPress($event)"'+ 
     'ng-focus="handleFocus($event)" ng-blur="handleBlur($event)"'+ 
     'ng-mousedown="handleMouseDown($event)"'+ 
     'ng-style="{\'left\': slider.left}"></a>'+ 
     '<div ng-style="{\'left\': slider.left}" ng-show="showVals" id="{{id}}-value" class="slider-value" role="presentation">{{slider.value}}</div>'+ 
    '</div>'); 
})); 

it('should compile and set the scope correctly', inject(function($compile, $rootScope) { 
    var element = $compile('<div slider min="6" max="18" step="1" ng-model="value"></div>')($rootScope); 
    $rootScope.$digest(); 

    var iScope = element.scope(); 

    iScope.$digest(); 

    console.log(iScope); 
    console.log(iScope.min); 
    console.log(element.html()); 
    console.log(element); 

    expect(element.html()).toContain("6"); 
    expect(element.find('div[class=min]').html()).toBe(6); 
    expect(iScope.min).toBe(6); 

})); 
}); 

這個控制檯輸出爲:

Scope{$id: '00T', $$childTail: null, $$childHead: null, $$prevSibling: null, $$nextSibling: null, $$watchers: null, $parent: null, $$phase: null, $root: Scope{$id: '00T', $$childTail: null, $$childHead: null, $$prevSibling: null, $$nextSibling: null, $$watchers: null, $parent: null, $$phase: null, $root: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., this: ..., $$destroyed: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$listeners: ..., $$isolateBindings: ..., safeApply: ...}, this: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., this: ..., $$destroyed: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$listeners: ..., $$isolateBindings: ..., safeApply: ...}, $$destroyed: false, $$asyncQueue: [], $$postDigestQueue: [], $$listeners: Object{}, $$isolateBindings: Object{}, safeApply: function (a) { ... }}, this: Scope{$id: '00T', $$childTail: null, $$childHead: null, $$prevSibling: null, $$nextSibling: null, $$watchers: null, $parent: null, $$phase: null, $root: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., this: ..., $$destroyed: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$listeners: ..., $$isolateBindings: ..., safeApply: ...}, this: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., this: ..., $$destroyed: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$listeners: ..., $$isolateBindings: ..., safeApply: ...}, $$destroyed: false, $$asyncQueue: [], $$postDigestQueue: [], $$listeners: Object{}, $$isolateBindings: Object{}, safeApply: function (a) { ... }}, $$destroyed: false, $$asyncQueue: [], $$postDigestQueue: [], $$listeners: Object{}, $$isolateBindings: Object{}, safeApply: function (a) { ... }} 
undefined 
'' 
{0: <div slider="" min="6" max="18" step="1" ng-model="value" class="ng-scope"></div>, length: 1} 

我有一個JSFiddle with the entire (slightly cleaned up) code,但也有它神祕甚至沒有讓過去的$編譯,這與我在本地的問題不一樣。不知道JSFiddle是否有用,因爲現在我有兩個神祕的問題,而不是一個。

回答

4

幾個月沒有回答或評論,而我在其他的東西上工作,現在我找到了答案。這真的很簡單:

$httpBackend.flush(); 

當您在一個單元測試使用$httpBackend.whenGET(),你總是需要刷新。所以當你使用templateUrl測試一個指令時,你需要在$ compile()之後使用flush()。

我希望這對那裏的人有用。

+0

我們爲什麼要衝洗? – learner 2015-04-03 11:15:53

+0

因爲GET不會立即返回。它是異步的,並且允許您在單元測試中使用它,您需要在需要AJAX調用返回時顯式清除。沒有它,天真的線性測試會稍微容易些,但是不可能測試您在生產中遇到的異步性所導致的問題。 – mcv 2015-04-05 23:40:32

+0

我懷疑你需要「flush()」只是因爲你使用「whenGET()」(獲取指令的HTML),但不一定是因爲你正在用templateUrl測試指令。在我的情況下,我已經將所有的html模板進行了預處理並存儲在$ templateCache中,因此「httpBackend.flush()」會拋出「錯誤:沒有待處理的請求刷新!」 – 2017-09-28 20:52:36