Come risolvere le promesse in Angularjs, Jasmine 2.0 quando non c'è $ portata per forzare un digest?
-
21-12-2019 - |
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();
});
. 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 chiamaredone
all'interno del metodothen
(o ilcatch
ofinally
), della promessa, dopo la risoluzione. Lo stai chiamando prima che la promessa si risolva, che sta causando la terminare la clausolait
.
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);
}));
.