2014-03-13 35 views
7

我在我的角度控制器的功能,看起來像下面這樣:角JS - 測試一個功能與頁面重定向使用噶/茉莉花

$scope.myFunction = function(){ 
    $scope.myVariable = "something"; 
    $scope.myOtherVariable = "something else"; 
    window.location.href = "/path/to/page"; 
} 

一個簡單的茉莉花測試涵蓋了上述功能,看起來像:

describe('my test', function(){ 
    it('should pass', function(){ 
     scope.myFunction(); 
     expect(scope.myVariable).toBe('something'); 
     expect(scope.myOtherVariable).toBe('something else');  
    }); 
}); 

上述測試本身通過,但隨後噶拋出在控制檯以下錯誤:

一些你的測試做了整頁重新加載!

頁面重定向導致Karma引發此警告。解決這個問題的最好方法是什麼?

我想到了在茉莉花測試和角度的名字給匿名函數,然後使用原始函數內部arguements.callee.caller.name以確定是否該函數是由自身或茉莉花調用。不幸的是,arguments.callee.caller.name總是返回undefined,我懷疑是由Angular和Jasmine相互鏈接引起的。

+0

這個問題實際上並沒有出現在我的代碼中,但它確實給了我點燃我自己修復程序的火花,所以感謝您發佈它!如果你好奇,我自己解決的問題是由於你的問題是http://stackoverflow.com/questions/31947852/how-to-test-angular-app-with-john-papa-style-karma-和茉莉花與數據-Servi大街。謝謝,C§ – CSS

回答

22

,因爲這個問題很長一段時間有人問,但下面的方法應該是清潔:

通過改變原有的功能,而不是使用瀏覽器窗口對象角的$窗口服務,就可以寫一個測試不需要修改生產代碼或考慮任何運行時參數。這當然要求$ window是發現函數的控制器的依賴關係。

使用angular-mocks/ngMock,是這樣的:

var fakeWindow = { 
    location: { 
    href: '' 
    } 
} 
// instantiate controller with mock window 
beforeEach(inject(function($controller) { 
    $controller('YourCtrlName', { 
    $window: fakeWindow 
    }); 
})); 

應該允許測試通過,假設控制器不需要$窗口爲別的。

+0

我認爲最完美的答案 – Maksym

+0

在大多數瀏覽器中,'window.location'是一個不可寫屬性,因此提供自己的假對象是模擬這些不可寫屬性的最佳方法。 – user2943490

+0

這應該是被接受的答案。您不必更改目標代碼即可使測試以當前接受的答案的方式運行。 – Red3

4

你可以只創建一個具有導航等

$scope.Navigate = function() { 
    window.location.href = "/path/to/page"; 
}; 

,甚至更好一些服務

app.factory('navigator', function() { 
    return { 
     Navigate: function(path) { 
      window.location.href = path; 
     } 
    }; 
}); 

然後在您的測試,你可以使用導航間諜功能,是確保導航已被調用,但實際上並未調用導航。