web-dev-qa-db-ja.com

Karma / jasmineでwindow.location関数をモックする方法

ダウンロードボタンをクリックした後にファイルを返すKarmaの機能を模擬したいと思います。次のAngularJSコントローラーがあります。

var secure = angular.module('secure', []);
secure.controller('ProcedureController', ProcedureController);
ProcedureController.$inject = ['$controller', '$rootScope', '$scope', '$http'];

function ProcedureController($controller, $rootScope, $scope, $http) {

  ... // Controller does more stuff

  var href = window.location.href.split('/');
  var baseUrl = href[0] + '//' + href[2];
  var url = baseUrl + "/secure/regulations";

  $http.get(url)
    .success(function (data) {
        $scope.questions = data[0];
    })

  $scope.download = function (msg) {
    window.location = url + "/" + msg + "/attachment";
  }
}

Window.locationオブジェクトは、目的のファイルを直接提供するRESTfulサービスを呼び出すだけです。そして、これは基本的に、私の試用テストです:

describe('ProcedureController', function () {
  beforeEach(module('secure'));

  beforeEach(inject(function ($rootScope, $http, $controller, $injector) {
    scope = $rootScope.$new();
    ProcedureController = $controller('ProcedureController', {
        $scope: scope,
        $http: $http
    });
  }));

  it ('should download something', function() {
    expect(scope.download(1)).toBeDefined();
  });

 });

したがって、私の考えは、scope.download関数が呼び出されたときに、正しいURLを返すかどうか、つまりscope.download(1)の場合、予想される答えは/ secure/regulations/1/attachmentになります。

どうやってあざけるの?どんな助けでもありがたいです!

14

代わりに $ window を使用してください:

var secure = angular.module('secure', []);
secure.controller('ProcedureController', ProcedureController);
ProcedureController.$inject = ['$controller', '$rootScope', '$scope', '$http', '$window'];

function ProcedureController($controller, $rootScope, $scope, $http, $window) {

  ... // Controller does more stuff

  var href = $window.location.href.split('/');
  var baseUrl = href[0] + '//' + href[2];
  var url = baseUrl + "/secure/regulations";

  $http.get(url)
    .success(function (data) {
        $scope.questions = data[0];
    })

  $scope.download = function (msg) {
    $window.location = url + "/" + msg + "/attachment";
  }
}

describe('ProcedureController', function () {
  var windowObj = {location: {href: ''}};

  beforeEach(mock.module(function($provide) {
     $provide.value('$window', windowObj);
  }));
  beforeEach(module('secure'));

  beforeEach(inject(function ($rootScope, $http, $controller, $injector) {
    scope = $rootScope.$new();
    ProcedureController = $controller('ProcedureController', {
        $scope: scope,
        $http: $http
    });
  }));

  it ('should download something', function() {
    expect(scope.download).toBeDefined();
    scope.download(1);
    expect(windowObj.location.href).toEqual('/secure/regulations/1/attachment');
  });

 });
14
Wawy

ここには多くの変数があると思いますが、テストから始めましょう。まず、なんらかの形式のブラウザをロードしているKarmaを介してJasmineテストを実行しているので、実際に「モックする」必要はありません。私希望PhantomJSのようなものの代わりにChromeを使用しています。

しかし、PhantomJSから始めましょう。テストのコードはおそらく次のようになります。

it ('should download something', function() {
  scope.download(1);
  expect(window.location).toBeDefined();
  expect(window.location).toBe('some static URL that it should be');
});

ただし、コントローラーの初期化を修正する必要があります。あなたはあなたがこのラインのニーズを満たすことができることを確認する必要があります:

var href = window.location.href.split('/');

つまり、ここでコントローラーを構築すると、

ProcedureController = $controller('ProcedureController', {

window.locationを何かに設定する必要があります$controllerを実行する前に、url変数を適切に構築します。

ここで、Chromeを使用している場合は、ブラウザで実際の動きが見られる可能性があります。これで問題が発生することはないと思いますが、必ずしも必要ではありません。これらのテストをコンソールで実行できるように、PhantomJSを使用するのが最適です。

0
Mike Perrenoud