web-dev-qa-db-fra.com

Comment se moquer d'une fonction window.location dans Karma/Jasmin

Je voudrais me moquer d'une fonctionnalité de Karma qui renvoie un fichier après avoir cliqué sur un bouton de téléchargement .. J'ai le contrôleur AngularJS suivant:

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";
  }
}

L'objet window.location appelle simplement un service RESTful qui lui fournit directement le fichier souhaité . Et voici, en gros, mon try-test:

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();
  });

 });

Donc, mon idée est de vérifier quand la fonction scope.download est appelée, si elle renvoie la bonne URL, à savoir, lorsque j'essaie scope.download (1), la réponse attendue serait/sécurisé/réglementation/1/pièce jointe , à peu près.

Comment dois-je m'en moquer? Toute aide est appréciée!

12
Hugoren Martinako

Utilisez $ window à la place:

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');
  });

 });
13
Wawy

Je suppose qu'il y a un certain nombre de variables ici, mais commençons par le test. Premièrement, vous n'avez pas vraiment besoin de "vous moquer" parce que vous exécutez un test Jasmine par Karma qui charge une forme de navigateur. Je _ {espère} _ vous utilisez PhantomJS au lieu de quelque chose comme Chrome.

Mais commençons par PhantomJS. Le code de votre test devrait probablement ressembler à ceci:

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

Cependant, vous devez corriger l'initialisation de votre contrôleur. Vous devez vous assurer que vous pouvez répondre au besoin de cette ligne:

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

Cela signifie que lorsque vous construisez votre contrôleur ici:

ProcedureController = $controller('ProcedureController', {

vous devrez définir window.location avec quelque chose avant d'exécuter $controller pour qu'il construise correctement la variable url.

Maintenant, si vous utilisez Chrome, vous constaterez probablement des mouvements réels dans le navigateur. Je ne pense pas que cela va causer de problèmes, mais ce n'est tout simplement pas nécessaire. Il vaudra mieux utiliser PhantomJS pour pouvoir exécuter ces tests dans la console.

0
Mike Perrenoud