Dies ist ein Controller mit einer Submit-Funktion:
$scope.submit = function(){
$http.post('/api/project', $scope.project)
.success(function(data, status){
$modalInstance.dismiss(true);
})
.error(function(data){
console.log(data);
})
}
}
Das ist mein Test
it('should make a post to /api/project on submit and close the modal on success', function() {
scope.submit();
$httpBackend.expectPOST('/api/project').respond(200, 'test');
$httpBackend.flush();
expect(modalInstance.dismiss).toHaveBeenCalledWith(true);
});
Der Fehler, den ich erhalte, ist:
Error: Unexpected request: GET views/appBar.html
views/appBar.html ist meine templateUrl:
.state('project', {
url: '/',
templateUrl:'views/appBar.html',
controller: 'ProjectsCtrl'
})
Irgendwie macht der UI-Router meinen $ httpBackend-Punkt darauf anstatt auf meine Submit-Funktion. Ich habe das gleiche Problem in allen meinen Tests mit $ httpBackend.
Gibt es eine Lösung dafür?
Nehmen Sie dieses Gist https://Gist.github.com/wilsonwc/8358542
angular.module('stateMock',[]);
angular.module('stateMock').service("$state", function($q){
this.expectedTransitions = [];
this.transitionTo = function(stateName){
if(this.expectedTransitions.length > 0){
var expectedState = this.expectedTransitions.shift();
if(expectedState !== stateName){
throw Error("Expected transition to state: " + expectedState + " but transitioned to " + stateName );
}
}else{
throw Error("No more transitions were expected! Tried to transition to "+ stateName );
}
console.log("Mock transition to: " + stateName);
var deferred = $q.defer();
var promise = deferred.promise;
deferred.resolve();
return promise;
}
this.go = this.transitionTo;
this.expectTransitionTo = function(stateName){
this.expectedTransitions.Push(stateName);
}
this.ensureAllTransitionsHappened = function(){
if(this.expectedTransitions.length > 0){
throw Error("Not all transitions happened!");
}
}
});
Fügen Sie es zu einer Datei namens stateMock in Ihrem Test/Mock-Ordner hinzu. Fügen Sie diese Datei in Ihre Karma-Konfiguration ein, falls sie noch nicht erfasst wurde.
Das Setup vor dem Test sollte dann ungefähr so aussehen:
beforeEach(module('stateMock'));
// Initialize the controller and a mock scope
beforeEach(inject(function ($state //other vars as needed) {
state = $state;
//initialize other stuff
}
Dann sollten Sie in Ihrem Test hinzufügen
state.expectTransitionTo('project');
In dieser Github-Ausgabe zu nit Testing UI Router wird ausführlicher erklärt, was passiert.
Das Problem ist, dass $httpBackend.flush()
eine Sendung auslöst, die dann den anderen Fall von stateProvider
auslöst.
Eine einfache Lösung kann sein, das folgende Setup durchzuführen, wie von @darinclark im oben erwähnten Github-Thread erwähnt. Dies gilt, wenn Sie keine Statusübergänge testen müssen. Ansonsten schauen Sie sich @ rosswils Antwort an, das von @ Vratislav Antwort auf Github inspiriert ist.
beforeEach(module(function ($urlRouterProvider) {
$urlRouterProvider.otherwise(function(){return false;});
}));
[~ # ~] bearbeitet [~ # ~]
Danke an Chris T, dies in den Kommentaren zu melden, scheint nach v0.2.14? Der beste Weg, dies zu tun, ist zu verwenden
beforeEach(module(function($urlRouterProvider) {
$urlRouterProvider.deferIntercept();
}));
Wenn Sie keine Gist-Dateien hinzufügen möchten, wie in der richtigen Lösung angegeben, können Sie Ihrem $ httpBackend eine "when" -Bedingung hinzufügen, um GET-Petitionen für Ansichten wie diese zu ignorieren:
$httpBackend.when("GET", function (url) {
// This condition works for my needs, but maybe you need to improve it
return url.indexOf(".tpl.html") !== -1;
}).passThrough();
Ich habe den gleichen Fehler kommentiert wie Sie, nach einem Anruf beim Service fragen sie mich nach der URL von sonst ui-route.
Um das Problem des Aufrufs zu lösen, lautet die ansonsten in ui-route enthaltene Anweisung nicht $ state injizieren in beforeeach. In meinem Testzustand hat $ keinen Sinn es zu benutzen.
Verschieben Sie Ihre Dienste in ein eigenes Modul, das nicht von ui.router abhängig ist. Habe deine Haupt-App von diesem Modul abhängig gemacht. Wenn Sie die Haupt-App nicht testen, testen Sie das Modul, in dem sich Ihre Dienste befinden. Der Zustandsanbieter versucht nicht, den Zustand/die Route zu ändern, da dieses Modul nichts über den ui.router weiß. Das hat bei mir funktioniert.