saya sudah myService
kegunaan itu myOtherService
, yang membuat panggilan jarak jauh, mengembalikan janji:
angular.module('app.myService', ['app.myOtherService'])
.factory('myService', [
myOtherService,
function(myOtherService) {
function makeRemoteCall() {
return myOtherService.makeRemoteCallReturningPromise();
}
return {
makeRemoteCall: makeRemoteCall
};
}
])
Untuk membuat unit test myService
saya perlu mengejek myOtherService
, sehingga makeRemoteCallReturningPromise
metodenya memberikan janji. Beginilah cara saya melakukannya:
describe('Testing remote call returning promise', function() {
var myService;
var myOtherServiceMock = {};
beforeEach(module('app.myService'));
// I have to inject mock when calling module(),
// and module() should come before any inject()
beforeEach(module(function ($provide) {
$provide.value('myOtherService', myOtherServiceMock);
}));
// However, in order to properly construct my mock
// I need $q, which can give me a promise
beforeEach(inject(function(_myService_, $q){
myService = _myService_;
myOtherServiceMock = {
makeRemoteCallReturningPromise: function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
}
};
}
// Here the value of myOtherServiceMock is not
// updated, and it is still {}
it('can do remote call', inject(function() {
myService.makeRemoteCall() // Error: makeRemoteCall() is not defined on {}
.then(function() {
console.log('Success');
});
}));
Seperti yang dapat Anda lihat di atas, definisi mock saya tergantung pada $q
, yang harus saya muat menggunakan inject()
. Selanjutnya, menyuntikkan mock harus terjadi module()
, yang harusnya terjadi sebelumnya inject()
. Namun, nilai untuk mock tidak diperbarui setelah saya mengubahnya.
Apa cara yang tepat untuk melakukan ini?
javascript
angularjs
unit-testing
mocking
jasmine
Georgii Oleinikov
sumber
sumber
myService.makeRemoteCall()
? Jika demikian, masalahnya adalahmyService
tidak memilikimakeRemoteCall
, tidak ada hubungannya dengan ejekan AndamyOtherService
.Jawaban:
Saya tidak yakin mengapa cara Anda melakukannya tidak berhasil, tetapi saya biasanya melakukannya dengan
spyOn
fungsi. Sesuatu seperti ini:Ingat juga bahwa Anda perlu membuat
$digest
panggilan agarthen
fungsi dipanggil. Lihat Pengujian bagian dari dokumentasi $ q .------ EDIT ------
Setelah melihat lebih dekat apa yang Anda lakukan, saya pikir saya melihat masalah dalam kode Anda. Dalam
beforeEach
, Anda mengaturmyOtherServiceMock
ke objek yang sama sekali baru. Tidak$provide
akan pernah melihat referensi ini. Anda hanya perlu memperbarui referensi yang ada:sumber
andCallFake
Anda dapat menggunakanandReturnValue(deferred.promise)
(atauand.returnValue(deferred.promise)
dalam Jasmine 2.0+). Anda harus menentukandeferred
sebelum meneleponspyOn
, tentu saja.$digest
dalam kasus ini ketika Anda tidak memiliki akses ke ruang lingkup?$rootScope
dan memanggil$digest
itu.$q.when()
codelord.net/2015/09/09/24/$q-dot-defer-youre-doing-it-wrongKita juga bisa menulis implementasi jasmine untuk mengembalikan janji secara langsung oleh mata-mata.
Untuk Jasmine 2:
(disalin dari komentar, terima kasih kepada ccnokes)
sumber
spyOn(myOtherService, "makeRemoteCallReturningPromise").and.returnValue($q.when({}));
Saya baru saja membunuh setengah jam mencari tahu itu.sumber
Anda dapat menggunakan pustaka mematikan seperti sinon untuk mengejek layanan Anda. Anda kemudian dapat mengembalikan $ q.when () sebagai janji Anda. Jika nilai objek lingkup Anda berasal dari hasil yang dijanjikan, Anda perlu memanggil lingkup. $ Root. $ Digest ().
sumber
$rootScope.$digest()
untuk mendapatkan janji untuk diselesaikanmenggunakan
sinon
:Diketahui itu,
httpPromise
bisa berupa:sumber
Jujur .. Anda melakukan ini dengan cara yang salah dengan mengandalkan inject untuk mengejek layanan, bukan modul. Juga, memanggil suntikan di beforeEach adalah anti-pola karena membuat mengejek sulit berdasarkan uji.
Inilah cara saya akan melakukan ini ...
Sekarang ketika Anda menyuntikkan layanan Anda, itu akan memiliki metode ejekan yang benar untuk penggunaan.
sumber
Saya menemukan bahwa fungsi layanan menusuk yang bermanfaat sebagai sinon.stub (). Mengembalikan ($ q.when ({})):
pengontrol:
dan uji
sumber
Cuplikan kode:
Dapat ditulis dalam bentuk yang lebih ringkas:
sumber