2015-06-17 12 views
12

Mi piacerebbe prendere in giro una funzionalità in Karma che restituisce un file dopo aver fatto clic su un pulsante di download. Ho la seguente controller AngularJS:Come imitare una funzione window.location in Karma/gelsomino

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'oggetto window.location basta chiamare un servizio RESTful che gli fornisce il file desiderato direttamente. E questo è, in fondo, la mia prova-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(); 
    }); 

}); 

Quindi, la mia idea è quella di verificare se scope.download funzione viene chiamata, se si restituisce l'URL destra, vale a dire, quando provo portata .download (1), la risposta prevista sarebbe /secure/rules/1/attachment, all'incirca.

Come si deve prendere in giro? Qualsiasi aiuto è apprezzato!

+0

C'è un motivo per cui non si utilizza '$ finestra 'o' $ location'? Questi potrebbero essere iniettati e puoi prenderli in giro usando 'inject()' https://docs.angularjs.org/api/ng/service/$window –

+0

Sì, hai ragione. Non me ne sono reso conto. Ora sto usando quella referenza. Grazie. –

risposta

13

Uso $window invece:

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

}); 
+0

Molto grato! Solo un piccolo feedback: in primo luogo, un po ', ho dovuto aggiungere 'angular.mock' per eseguirlo. Ma il problema principale era che la funzione mock restituiva sempre un 'indefinito' nella proprietà href (anche se era diverso dal vuoto). Quindi, ho dovuto ottenere solo 'windowObj.location'. Naturalmente, il valore di ritorno era diverso, ma questo è solo un problema di analisi. Sapere perché? –

+0

Nel tuo codice stai assegnando '$ window.location = url +"/"+ msg +"/attachment ";' invece di '$ window.location.href', potrebbe essere? – Wawy

+0

Yepp! Abbastanza vicino!Basta aggiungere un host falso a 'windowObj' (e la risposta attesa). Altrimenti, avremo un host _undefined_, ma il percorso giusto. –

-1

Suppongo che ci siano un certo numero di variabili qui, ma iniziamo con il test. Innanzitutto, non è necessario "deriderlo" perché stai eseguendo un test Jasmine tramite Karma che sta caricando una qualche forma di browser. I speranza si sta usando PhantomJS invece di qualcosa come Chrome.

Ma iniziamo con PhantomJS. Il codice per il test dovrebbe probabilmente simile a questa:

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

Tuttavia, è necessario sistemare l'inizializzazione per il controller. È necessario assicurarsi la possibilità di soddisfare il bisogno di questa linea:

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

Ciò significa che quando si genera il controller qui:

ProcedureController = $controller('ProcedureController', { 

si sta andando ad avere bisogno di impostare il window.location a qualcosa prima di eseguire $controller in modo da creare correttamente la variabile url.

Ora, se si utilizza Chrome, è probabile che si vedano movimenti reali nel browser. Non penso che questo causerà problemi ma non è solo necessario. È preferibile utilizzare PhantomJS in modo che sia possibile eseguire tali test nella console.

Problemi correlati