2015-06-17 6 views
12

Ich möchte eine Funktionalität in Karma verspotten, die eine Datei nach dem Klicken auf eine Download-Schaltfläche zurückgibt. Ich habe folgendes AngularJS Controller:Wie man eine window.location Funktion in Karma/Jasmin spottet

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

Das window.location Objekt nur einen RESTful Dienst rufen, die ihm direkt die gewünschte Datei zur Verfügung stellt. Und das ist im Grunde genommen mein 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(); 
    }); 

}); 

So ist meine Idee zu überprüfen, wenn scope.download Funktion aufgerufen wird, wenn es die richtige URL zurückgibt, nämlich dann, wenn ich Umfang versuchen .download (1), die erwartete Antwort wäre /secure/Vorschriften/1/Anhang, grob.

Wie soll ich mich verspotten? Jede Hilfe wird geschätzt!

+0

Gibt es einen Grund, warum Sie nicht '$ window' oder' $ location' verwenden? Diese könnten injiziert werden und Sie können sie mit 'inject()' spotten https://docs.angularjs.org/api/ng/service/$window –

+0

Ja, Sie haben Recht. Ich habe es einfach nicht bemerkt. Jetzt benutze ich diese Referenz. Danke. –

Antwort

13

Verwenden $window statt:

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

Sehr dankbar! Nur ein kleines Feedback: Zuerst, eine Kleinigkeit, musste ich 'angular.mock' hinzufügen, um es auszuführen. Aber das Hauptproblem war, dass die Scheinfunktion immer eine "undefiniert" in der href-Eigenschaft zurückgab (auch wenn sie sich von leer unterschied). Also musste ich stattdessen nur 'windowObj.location' bekommen. Natürlich war der Rückgabewert anders, aber das ist nur ein Parse-Problem. Wissen warum? –

+0

In Ihrem Code geben Sie '$ window.location = url +"/"+ msg +"/attachment ";' anstelle von '$ window.location.href', könnte es das sein? – Wawy

+0

Yepp! Nahe genug!Das Hinzufügen eines falschen Hosts zu "windowObj" funktioniert (und die erwartete Antwort). Andernfalls haben Sie einen _undefined_ Host, aber den richtigen Pfadnamen. –

-1

Ich denke, es gibt eine Reihe von Variablen hier, aber lassen Sie uns mit dem Test beginnen. Zuerst müssen Sie nicht wirklich "nachspotten", weil Sie einen Jasmine-Test durch Karma ausführen, der irgendeine Art von Browser lädt. Ich hoffe Sie verwenden PhantomJS anstelle von etwas wie Chrome.

Beginnen wir aber mit PhantomJS. Der Code für Ihren Test sollte wohl so etwas wie folgt aussehen:

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

Allerdings müssen Sie die Initialisierung für Ihren Controller reparieren. Sie müssen sicherstellen, dass Sie die Notwendigkeit dieser Linie erfüllen:

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

Dies bedeutet, dass, wenn Sie Ihren Controller bauen hier:

ProcedureController = $controller('ProcedureController', { 

Sie die window.location auf etwas festgelegt sind gehen zu müssen, vor der Ausführung $controller, so dass es die url Variable ordnungsgemäß erstellt.

Jetzt, wenn Sie Chrome verwenden, dann werden Sie wahrscheinlich echte Bewegung im Browser sehen. Ich denke nicht, dass dies Probleme verursachen wird, aber es ist einfach nicht notwendig. Es wird am besten sein, PhantomJS zu verwenden, damit Sie diese Tests in der Konsole ausführen können.

Verwandte Themen