1.beforeEach(inject(){...})中的代碼會在beforeEach所在的describe中的每個it(包括子describe中的it)前執行一次。
2.假如it不是寫在describe中而是寫在另外一個it中則it中的內容不會被執行,且beforeEach不會執行。同理inject不是寫在beforeEach中也不會被執行(能夠寫在it中執行)。
可能這裏是使用了隊列,在describe中執行it()時往隊列裏添,而寫在it中的it在被執行時隊列已經不接受加入了。
3.inject能夠寫在it中,甚至能寫成it('', inject(...))
4.每一個inject會從新運行一次run。也會從新生成一次$rootScope
5.關於karma的假裝響應。
使用$httpBackend.when(...).respond(200, data)來返回data。
假如要將本地html等文件做爲上述data返回呢?
1. 首先須要利用$templateCache服務,本服務容許$http服務緩存通過XHR的模板請求。當一個模板被取到了,它的內容就會存儲在$templateCache中,用模板路徑作參數獲取。
獲取方式:$templateCache.get('xx.html')
2. 問題是如何將本地的xx.html放到$templateCache裏呢?
咱們寫代碼當然能夠經過$templateCache.put('xx.html', ...)來往裏面放內容,但本地的文件須要將模板轉換成可在測試中使用的ng模塊。
解決方案爲使用karma-ng-html2js-preprocessor包來作轉換工做。
[以上參考 《AngularJS權威教程》 19.14.7 p268]
首先須要安裝包:
$ npm install --save-dev karma-ng-html2js-preprocessor
而後須要修改karma.conf.js:
files: [
'**/*.html'
],
preprocessors: {
'**/*.html': ['ng-html2js']
},
ngHtml2JsPreprocessor: {
moduleName: 'templates' // 這個是模塊名字,隨意取,
cacheIdFromPath: function(filepath){
return filepath // 這裏獲取到的filepath,是在上面files裏定義的路徑。然而這個路徑與【被測試腳本】裏所用的路徑,可能由於根目錄的不一樣而有差別。因此能夠在這裏作處理轉成與測試腳本同樣的路徑,這樣在【測試代碼】裏就能用這個路徑獲取到html了,即$templateCache('xxx'),xxx與被測試腳本的路徑一致。
},
stripPrefix: ''
}
而後在test.js裏先寫:
beforeEach(module('templates'))
beforeEach(module('mainApp'))
【注意,必定要先加載templates模塊,再加載你的模塊。若是反過來,而你的模塊中run中動態編譯指令,又使用了$digest要當即渲染,這時會直接須要獲取模板文件,但因爲templates模塊未加載沒法獲取文件,會報錯:Error: Unexpected request: GET test/myDirective.html】
【也許是因爲模板直接寫到$templateCache裏,因此不須要經過設置$httpBackend.when來假裝響應,更不須要$httpBackend.flush()】
而後這時假裝響應就能在收到響應時返回文件
$httpBackend.when('GET', 'test/myDirective.html').respond(200, $templateCache.get('test/myDirective.html'))
【注意$httpBackend.when必須在被測試文件發起請求前設置】
在it中沖刷請求:
it('發送請求', function(){
$httpBackend.flush()
})
6. $httpBackend.flush()貌似只能使用一次。
it('1', function(){
$httpBackend.when(...).respond(...);$httpBackend.flush();
})
it('2', function(){
$httpBackend.when(...).respond(...);$httpBackend.flush();
})
這樣會致使2裏的when沒法返回。改爲如下則能夠:
it...$http...respond(...)
it...$http...respond(...)
it...$httpBackend.flush()
7.$http的使用方法對$httpBackend.when有影響
$httpBackend.when以下:
$httpBackend.when('GET','/js/apps/main/tpl/questionEntry.html',function(){
console.log('a')
return true
})
.respond(200,$templateCache.get('/js/apps/main/tpl/questionEntry.html'))
而使用$http({method: 'GET', url:...})時,能按理console;使用$http.get('...')時,則不能console
8.假如請求的url後面有時間戳,怎麼才能在$httpBackend裏獲取到data呢?這裏彷佛從某個環節開始,都不會將時間戳做爲data處理,因此致使when的第三個參數沒法被調用。
解決方案以下:
$httpBackend.when('GET', {
test: function(url){
var str = '/js/apps/main/tpl/questionEntry.html'
return url.indexOf(str) != -1
}
})
.respond(200,$templateCache.get('/js/apps/main/tpl/questionEntry.html'))
請求使用directive、$http均可以發送。
9.在作inject注入時,若是屢次注入,要注意每次所獲取到的服務都是全新的。因此當第二個inject裏的服務與第一個inject裏的服務混用時會產生問題。html