Come risolvere le promesse in Angularjs, Jasmine 2.0 quando non c'è $ portata per forzare un digest?

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

Domanda

Sembra che promette Non risolvere in angolarmente/ Test del gelsomino a meno che non forzasse un $scope.$digest() .Questo è sciocco imo ma bene, ho quel lavoro dove applicabile (controller).

La situazione in cui sono ora è che ho un servizio che potrebbe interessare meno di qualsiasi ambito nell'applicazione, tutto ciò che restituisce alcuni dati dal server ma la promessa non sembra risolvere. .

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();
    });
  });
});
.

Qual è il modo corretto per testare questa funzionalità?

Modifica: soluzione per riferimento.Apparentemente si è costretti a iniettare e digerire la $ Roottscope anche se il servizio non lo usa.

  it('should get something', function($rootScope, done) {
    var promise = myService.getSomething();

    promise.then(function(resp) {
      expect(resp).toBe('test');      
    });

    $rootScope.$digest();
    done();
  }); 
.

È stato utile?

Soluzione

È necessario iniettare $rootScope nel test e innescare $digest su di esso.

Altri suggerimenti

C'è sempre $ rootscope, usalo

inject(function($rootScope){
myRootScope=$rootScope;
})
....

myRootScope.$digest();
.

Quindi ho lottato con questo tutto il pomeriggio. Dopo aver letto questo post, anch'io ho sentito che c'era qualcosa di spento con la risposta; si scopre che c'è. Nessuna delle risposte di cui sopra fornisce una chiara spiegazione su dove e perché utilizzare $rootScope.$digest. Quindi, ecco cosa ho trovato.

Prima di tutto il perché? È necessario utilizzare $rootScope.$digest ogni volta che rispondi da un evento non angolare o callback. Ciò includerebbe gli eventi Dom pure, gli eventi jquery e altre librerie promette di terze parti diverse da $q che fa parte dell'angolare.

secondamente dove? Nel tuo codice, non il tuo test. Non è necessario iniettare $rootScope nel test, è necessario solo nel tuo servizio angolare reale. È qui che tutto quanto sopra non riesce a chiarire quale sia la risposta, mostrano $rootScope.$digest come chiamato dal test.

Spero che questo aiuti la prossima persona che arriva a lungo che ha la stessa questione.

Aggiornamento


.

Ho cancellato questo post ieri quando è stato votato. Oggi ho continuato a avere questo problema cercando di usare le risposte, gentilmente fornito sopra. Quindi, sono di standby la mia risposta al costo dei punti di reputazione, e come tale, lo sto indeterminato.

Questo è ciò di cui hai bisogno nei gestori di eventi non angolare e stai usando $ Q e stai cercando di testare con il gelsomino.

something.on('ready', function(err) {
    $rootScope.$apply(function(){deferred.resolve()});              
});
.

.

Si noti che potrebbe essere necessario essere avvolti in un timeout di $ in un caso.

something.on('ready', function(err) {
    $timeout(function(){
      $rootScope.$apply(function(){deferred.resolve()});    
    });     
});
.

.

un'altra nota. Negli esempi di problemi originali stai chiamando done nel momento sbagliato. È necessario chiamare done all'interno del metodo then (o il catch o finally), della promessa, dopo la risoluzione. Lo stai chiamando prima che la promessa si risolva, che sta causando la terminare la clausola it.

dalla documentazione angolare.

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);
}));
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top