javascript - Bagaimana saya menyelesaikan promise dalam ujian unit AngularJS
Saya sedang menggunakan set up karma/jasmine asas untuk menguji kod Angular saya. Ini adalah ujian saya:
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;
describe('main controller', function() {
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;
beforeEach(inject(function($controller, $rootScope, $q) {
scope = $rootScope.$new();
$controllerConstructor = $controller;
q = $q;
mockSuperheroData = {
getSuperheroes: function() {
deferred = q.defer();
return deferred.promise;
}
};
ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}});
}));
it('should set the result of getResource to scope.heroes', function() {
scope.getHeroes();
expect(scope.heroes).toBe(100);
});
}
scope.getHeroes() memanggil mockSuperheroData.getSuperheroes() yang mengembalikan janji (promise). Bagaimana saya boleh memaksa janji itu untuk mengembalikan apa yang saya mahukan dalam ujian unit? Di mana saya boleh sambungkan ke janji itu untuk meniru (mock) kembalianannya?
Jawapan #1
Bagaimana saya boleh memaksa janji itu untuk mengembalikan apa yang saya mahukan dalam ujian unit?
Pada dasarnya anda perlu memanggil resolve pada Deferred:
deferred.resolve(100);
Anda boleh meletakkan itu terus sebelum return deferred.promise atau dalam setTimeout asynchronous.
Jawapan #2
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;
describe('main controller', function() {
var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q, rootScope;
beforeEach(inject(function($controller, $rootScope, $q) {
scope = $rootScope.$new();
$controllerConstructor = $controller;
q = $q;
rootScope = $rootScope;
mockSuperheroData = {
getSuperheroes: function() {
deferred = q.defer();
return deferred.promise;
}
};
ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}});
}));
it('should set the result of getResource to scope.heroes', function() {
scope.getHeroes();
deferred.resolve(100);
rootScope.$apply();
expect(scope.heroes).toBe(100);
});
});
Perlu disebutkan bahawa kerana $q diintegrasikan dengan $rootScope, bukan sahaja anda perlu menyelesaikan objek tertangguh itu, tetapi anda juga perlu menyebarkan perubahan dengan memanggil $rootScope.$apply.
Saya menulis sebuah blog tentang memperolok janji angular di projectpoppycock
dan saya menulis contoh yang berfungsi, dengan ujian, di plunkr
Saya sangat menyukai cara anda menyuntikkan perkhidmatan tiruan sebagai kebergantungan pengawal dengan menggunakan perkhidmatan $controller, saya mungkin perlu menilai semula cara saya melakukan ini. Cara anda lebih baik :) Terima kasih!
