Comment faire pour résoudre les promesses dans AngularJS, Jasmin 2.0 quand il n'y a pas de $champ d'application de la force d'un résumé?
-
21-12-2019 - |
Question
Il semble que les promesses ne résolvent pas dans Angulaire/Jasmin tests, sauf si vous forcez un $scope.$digest()
.C'est stupide de l'OMI, mais fine, je n'ai que de travail, le cas échéant (les contrôleurs).
La situation que je suis maintenant est que j'ai un service qui ne s'intéressent pas à toutes portées dans l'application, il ne revient quelques données à partir du serveur, mais la promesse ne semble pas être la résolution.
app.service('myService', function($q) {
return {
getSomething: function() {
var deferred = $q.defer();
deferred.resolve('test');
return deferred.promise;
}
}
});
describe('Method: getSomething', function() {
// In this case the expect()s are never executed
it('should get something', function(done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
expect(1).toEqual(2);
});
done();
});
// This throws an error because done() is never called.
// Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
it('should get something', function(done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
expect(1).toEqual(2);
done();
});
});
});
Quelle est la bonne façon de tester cette fonctionnalité?
Edit:La Solution de référence.Apparemment, vous êtes obligé d'injecter et de digérer l' $rootScope même si le service n'est pas à l'utiliser.
it('should get something', function($rootScope, done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
});
$rootScope.$digest();
done();
});
La solution
Vous avez besoin d'injecter $rootScope
dans votre test et de déclencher $digest
sur elle.
Autres conseils
il y a toujours de l' $rootScope, l'utiliser
inject(function($rootScope){
myRootScope=$rootScope;
})
....
myRootScope.$digest();
Donc, j'ai de la difficulté avec ce tout l'après-midi.Après la lecture de ce post, j'ai aussi senti qu'il y avait quelque chose avec la réponse;il s'avère qu'il y est.Aucune des réponses ci-dessus, de donner une explication claire de quand et pourquoi utiliser l' $rootScope.$digest
.Voici donc ce que je suis venu avec.
Tout d'abord, pourquoi?Vous avez besoin d'utiliser $rootScope.$digest
chaque fois que vous répondez à partir d'un non-angulaire de l'événement ou de rappel.Cela permettrait de comprendre pur événements DOM, jQuery événements, et d'autres de la 3e partie de la Promesse des bibliothèques autres que $q
qui est la partie angulaire.
D'autre part, lorsque?Dans votre code, PAS de test.Il n'est pas nécessaire d'injecter $rootScope
dans ton test, il est uniquement nécessaire dans votre angulaire de service.C'est là que tous les ci-dessus ne parviennent pas à rendre clair ce que la réponse est, ils montrent $rootScope.$digest
que d'être appelé à partir de l'essai.
J'espère que cela aide la personne à côté de qui vient le long qui a est du même sujet.
Mise à jour
J'ai supprimé ce post hier, quand il a été voté en bas.Aujourd'hui, j'ai continué à avoir ce problème en essayant d'utiliser les réponses, gracieusement fourni ci-dessus.Donc, je veille à ma réponse sur le coût de points de réputation, et en tant que tel , je suis la suppression d'elle.
C'est ce que vous avez besoin dans les gestionnaires d'événements qui sont non-angulaire, et vous êtes à l'aide de $q et essayer de tester avec le Jasmin.
something.on('ready', function(err) {
$rootScope.$apply(function(){deferred.resolve()});
});
Notez qu'il peut avoir besoin d'être enveloppé dans un $timeout dans certains cas.
something.on('ready', function(err) {
$timeout(function(){
$rootScope.$apply(function(){deferred.resolve()});
});
});
Une remarque plus.Dans le problème original exemples que vous appelez
done
au mauvais moment.Vous devez appelerdone
à l'intérieur de lathen
de la méthode (ou lacatch
oufinally
), de la promesse, après est décide.Vous êtes en l'appelant avant que la promesse se résout, qui est à l'origine de lait
la clause de résiliation.
À partir de l'angle de la documentation.
https://docs.angularjs.org/api/ng/service/$q
it('should simulate promise', inject(function($q, $rootScope) {
var deferred = $q.defer();
var promise = deferred.promise;
var resolvedValue;
promise.then(function(value) { resolvedValue = value; });
expect(resolvedValue).toBeUndefined();
// Simulate resolving of promise
deferred.resolve(123);
// Note that the 'then' function does not get called synchronously.
// This is because we want the promise API to always be async, whether or not
// it got called synchronously or asynchronously.
expect(resolvedValue).toBeUndefined();
// Propagate promise resolution to 'then' functions using $apply().
$rootScope.$apply();
expect(resolvedValue).toEqual(123);
}));