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é?

StackOverflow https://stackoverflow.com//questions/24021031

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();
  }); 
Était-ce utile?

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 appeler done à l'intérieur de la then de la méthode (ou la catch ou finally), 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 la it 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);
}));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top