Ich schreibe Jasmine-Komponententests für meine App in Typescript und führe sie über Resharper aus. Es soll eine Aktion ausführen, wenn der Handler eine Ausnahme auslöst:
describe("Q Service Test", () => {
var q: ng.IQService;
var rootScope: ng.IRootScopeService;
beforeEach(inject(($q, $rootScope) => {
q = $q;
rootScope = $rootScope;
}));
it("Caught exceptions are handled properly", () => {
var state = 'ok';
q.when(1)
.then(() => {
throw new Error("test exception");
})
.catch(() => {
state = 'error';
});
rootScope.$digest();
expect(state).toBe('error');
});
});
Der Test ist jedoch fehlgeschlagen:
Ist es ein seltsames Verhalten meiner Testumgebung / Tools oder verwende ich den Versprechensmechanismus selbst falsch?
Sie verwenden den Versprechensmechanismus definitiv falsch . Wenn Sie eine benutzerdefinierte Wurfanweisung auslösen , bedeutet dies nicht, dass Sie sie als Ablehnung eines Versprechens richtig abfangen. Wie in der $q
Dokumentation angegeben:
Wenn deferreds / Versprechen dem bekannten Verhalten von try / catch / throw zu vergleichen, denken Sie an ablehnen als throw in JavaScript - Schlüsselwort. Dies bedeutet auch, dass Sie, wenn Sie einen Fehler über einen Versprechungsfehler-Rückruf "abfangen" und den Fehler an das aus dem aktuellen Versprechen abgeleitete Versprechen weiterleiten möchten, den Fehler "zurückwerfen" müssen, indem Sie eine durch Zurückweisen erstellte Ablehnung zurückgeben.
Sie sind ähnlich, aber nicht äquivalent. Um benutzerdefinierte throw-Anweisungen abzufangen, sollten Sie catch
Anweisungsblöcke verwenden. Während $q
Versprechen nur catch
Versprechen ablehnen sollten . In Ihrem Fall ist die Rückgabe eines abgelehnten Versprechens daher die richtige Vorgehensweise, anstatt eine benutzerdefinierte Ausnahme auszulösen.
JAVASCRIPT
describe('Q Service Test', function() {
var $q,
$rootScope;
beforeEach(inject(function(_$q_, _$rootScope_) {
$q = _$q_;
$rootScope = _$rootScope_;
}));
it('Rejected promises are handled properly', function() {
var state = 'ok';
$q.when(1)
.then(function() {
return $q.reject('rejected');
})
.catch(function() {
state = 'error';
});
$rootScope.$digest();
expect(state).toBe('error');
});
});
AKTUALISIEREN:
Der Grund, warum sich Ihr Code im Browser so verhält, liegt darin, dass die $q
Implementierung von Angular die try/catch
Anweisungsblöcke bei der Verarbeitung der Versprechungswarteschlange verwendet. Wenn einer der Rückrufe Fehler auslöst, fängt er den Fehler selbst ab, lehnt ihn mit der Ausnahme als Grund für die Ablehnung ab und $exceptionHandler
protokolliert anschließend den Fehler. Ich empfehle Ihnen, das abgelehnte Versprechen einfach zurückzugeben.
Der Grund, warum die Komponententests so ablaufen, liegt in der angular-mocks
Implementierung, die $exceptionHandler
sich von der tatsächlichen Anwendung unterscheidet $exceptionHandler
. Ersteres erstellt einen Anbieter mit verschiedenen Modi. Die Standard-Angle-Mocks-Implementierung verwendet den rethrow
Modus, der wiederum die Ausnahme auslöst, anstatt sie zu protokollieren. Wenn Sie möchten, dass sich Ihre Komponententests genauso verhalten wie die Standardanwendung, können $exceptionHandler
Sie den Modus auf einstellen 'log'
.
JAVASCRIPT
describe('Q Service Test', function() {
var $q,
$rootScope;
beforeEach(module('ng', function($exceptionHandlerProvider) {
$exceptionHandlerProvider.mode('log');
}));
beforeEach(inject(function(_$q_, _$rootScope_) {
$q = _$q_;
$rootScope = _$rootScope_;
}));
it('Caught exceptions are handled properly', function() {
var state = 'ok';
$q.when(1)
.then(function() {
throw new Error();
})
.catch(function() {
state = 'error';
});
$rootScope.$digest();
expect(state).toBe('error');
});
});
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen