7

Angular コントローラーに次のような関数があります。

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

簡単な Jasmine テストは上記の関数をカバーし、次のようになります。

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

上記のテスト自体はパスしますが、Karma はコンソールに次のエラーをスローします。

一部のテストでページ全体がリロードされました。

ページ リダイレクトにより、Karma はこの警告を表示します。これを回避する最善の方法は何ですか?

Jasmine テストで無名関数と Angular 名の両方を指定し、元の関数内でArguments.callee.caller.nameを使用して、関数がそれ自体または Jasmine によって呼び出されているかどうかを判断することを考えました。残念ながら、arguments.callee.caller.nameは常に undefined を返します。これは、Angular と Jasmine が相互にリンクされていることが原因であると思われます。

4

2 に答える 2

22

この質問が出されてから長い時間が経ちましたが、次のアプローチはよりクリーンである必要があります。

ブラウザ ウィンドウ オブジェクトの代わりに Angular の $window サービスを使用するように元の関数を変更することで、本番コードの変更やランタイム パラメータを考慮に入れる必要のないテストを作成できます。もちろん、これには $window が関数が見つかったコントローラーの依存関係であることが必要です。

angular-mocks/ngMockを使用すると、次のようになります。

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

コントローラーが他の目的で $window を必要としないと仮定して、テストに合格できるようにする必要があります。

于 2014-12-01T22:08:03.670 に答える
4

次のようなナビゲーションを行う関数を作成できます

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

またはいくつかのサービスでさらに良い

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

次に、テストで Navigate でスパイを使用して、ナビゲーションが呼び出されたことを確認できますが、実際にはナビゲーションを呼び出さないでください。

于 2014-03-13T20:57:48.157 に答える