Подтвердить что ты не робот

Как издеваться над функцией 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/rules/1/вложение, примерно.

Как мне это издеваться? Любая помощь приветствуется!

4b9b3361

Ответ 1

Вместо этого используйте $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');
  });

 });

Ответ 2

Я думаю, здесь есть несколько переменных, но пусть начнется с теста. Во-первых, вам не нужно "издеваться над этим", потому что вы запускаете тест Jasmine через Karma, который загружает какую-то форму браузера. Я надеюсь вы используете 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, чтобы вы могли запускать те тесты в консоли.