Ich versuche, eine Antwort auf eine JSONP GET-Anfrage zu verspotten, die mit einer Funktion gemacht wird, die eine ES6-Versprechen zurückgibt, die ich in $q.when()
verpackt habe. Der Code selbst funktioniert gut, aber in den Unit-Tests wird die Anfrage nicht von $ httpBackend abgefangen und geht direkt zur eigentlichen URL über. Wenn also flush()
aufgerufen wird, erhalte ich einen Fehler unter der Nummer Error: No pending request to flush !
. Die JSONP-Anforderung wird über die $.getJSON()
-Komponente von jQuery im ES6-Versprechen gestellt. Daher habe ich mich dafür entschieden, alle ausgehenden Anforderungen abzufangen, indem ich eine Regex anstelle einer fest codierten URL zur Verfügung stelle.
Ich habe überall auf der Suche nach diesem herauszufinden für eine Weile jetzt und immer noch zu verstehen, was den Anruf verursacht, durch zu gehen. Ich habe das Gefühl, dass die HTTP-Anfrage im ES6-Versprechen "außerhalb von Angular" gemacht wird, so dass $ httpBackend nichts davon weiß/nicht in der Lage ist, es zu fangen, obwohl das nicht der Fall ist, wenn der Anruf getätigt wurde innerhalb eines $ q Versprechens von Anfang an. Kann mir jemand vielleicht sagen, warum dieser Anruf durchkommt und warum eine einfache Zeitüberschreitung gut funktioniert? Ich habe alle Kombinationen von $scope.$apply
, $scope.$digest
und hier versucht, aber ohne Erfolg.
Vielleicht besser einige Code wird es erklären ...
-Controller
function homeController() {
...
var self = this;
self.getData = function getData() {
$q.when(user.getUserInformation()).then(function() {
self.username = user.username;
});
};
}
Einheit Test
...
beforeEach(module('home'));
describe('Controller', function() {
var $httpBackend, scope, ctrl;
beforeEach(inject(function(_$httpBackend_, $rootScope, $componentController) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new(); // used to try and call $digest or $apply
// have also tried whenGET, when('GET', ..), etc...
$httpBackend.whenJSONP(/.*/)
.respond([
{
"user_information": {
"username": "TestUser",
}
}
]);
ctrl = $componentController("home");
}));
it("should add the username to the controller", function() {
ctrl.getData(); // make HTTP request
$httpBackend.flush(); // Error: No pending request to flush !
expect(ctrl.username).toBe("TestUser");
});
});
...
Aus irgendeinem Grund funktioniert dies jedoch:
it("should add the username to the controller", function() {
ctrl.getData(); // make HTTP request
setTimeout(() => {
// don't even need to call flush, $digest, or $apply...?
expect(ctrl.username).toBe("TestUser");
});
});
httpBackend ist eine Mock-Implementierung, die in die $ HTTP-Dienst durch Winkel für die Unit-Tests eingespritzt wird, wenn Sie nicht den $ http-Dienst verwenden zu machen Bei einer Anfrage können Sie das httpBackend nicht verwenden, um es abzufangen –