Saya memiliki layanan AngularJS tertulis dan saya ingin mengujinya.
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) {
this.something = function() {
// Do something with the injected services
};
return this;
});
File app.js saya terdaftar sebagai berikut:
angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)
Saya dapat menguji DI bekerja seperti itu:
describe("Using the DI framework", function() {
beforeEach(module('fooServiceProvider'));
beforeEach(module('barServiceProvider'));
beforeEach(module('myServiceProvder'));
var service;
beforeEach(inject(function(fooService, barService, myService) {
service=myService;
}));
it("can be instantiated", function() {
expect(service).not.toBeNull();
});
});
Ini membuktikan bahwa layanan dapat dibuat oleh kerangka DI, namun selanjutnya saya ingin menguji layanan unit, yang berarti mengejek objek yang diinjeksi.
Bagaimana cara saya melakukan ini?
Saya sudah mencoba memasukkan objek tiruan saya ke dalam modul, misalnya
beforeEach(module(mockNavigationService));
dan menulis ulang definisi layanan sebagai:
function MyService(http, fooService, barService) {
this.somthing = function() {
// Do something with the injected services
};
});
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })
Tapi yang terakhir tampaknya menghentikan layanan yang dibuat oleh DI seperti semua.
Adakah yang tahu bagaimana saya bisa mengejek layanan yang disuntikkan untuk tes unit saya?
Terima kasih
David
javascript
angularjs
mocking
jasmine
angularjs-service
BanksySan
sumber
sumber
Jawaban:
Anda dapat menyuntikkan ejekan ke layanan Anda dengan menggunakan
$provide
.Jika Anda memiliki layanan berikut dengan dependensi yang memiliki metode yang disebut getSomething:
Anda dapat memasukkan versi tiruan myDependency sebagai berikut:
Perhatikan bahwa karena panggilan ke
$provide.value
Anda sebenarnya tidak perlu memasukkan myDependency secara eksplisit di mana pun. Itu terjadi di bawah kap selama injeksi myService. Saat menyiapkan mockDependency di sini, itu bisa dengan mudah menjadi mata-mata.Terima kasih kepada loyalBrown atas tautan ke video hebat itu .
sumber
beforeEach(module('myModule'));
panggilan HARUS datang sebelumbeforeEach(function () { MOCKING })
panggilan, atau ejekan akan ditimpa oleh layanan yang sebenarnya!$provide
panggilan apa pun harus dilakukan sebelum menggunakan$injector
, jika tidak, Anda akan menerima kesalahan:Injector already created, can not register a module!
Error: [ng:areq] Argument 'fn' is not a function, got Object
, pastikan untuk memberireturn
baris setelahnya$provide.value(...)
. Kembali secara implisit$provide.value(...)
menyebabkan kesalahan itu bagi saya.Cara saya melihatnya, tidak perlu mengejek layanan itu sendiri. Cukup tiru fungsi pada layanan. Dengan begitu, Anda dapat memiliki angular menyuntikkan layanan nyata Anda seperti halnya di seluruh aplikasi. Kemudian, tiru fungsi pada layanan sesuai kebutuhan menggunakan
spyOn
fungsi Jasmine .Sekarang, jika layanan itu sendiri adalah sebuah fungsi, dan bukan objek yang dapat Anda gunakan
spyOn
, ada cara lain untuk melakukannya. Saya perlu melakukan ini, dan menemukan sesuatu yang bekerja cukup baik untuk saya. Lihat Bagaimana Anda mengejek layanan Angular yang merupakan fungsi?sumber
Opsi lain untuk membantu membuat dependensi tiruan lebih mudah di Angular dan Jasmine adalah dengan menggunakan QuickMock. Ini dapat ditemukan di GitHub dan memungkinkan Anda membuat tiruan sederhana dengan cara yang dapat digunakan kembali. Anda dapat mengkloningnya dari GitHub melalui tautan di bawah ini. README cukup jelas, tapi semoga bisa membantu orang lain di masa depan.
https://github.com/tennisgent/QuickMock
Ini secara otomatis mengelola semua boilerplate yang disebutkan di atas, jadi Anda tidak perlu menulis semua kode injeksi tiruan itu di setiap pengujian. Semoga membantu.
sumber
Selain jawaban John Galambos : jika Anda hanya ingin mengejek metode tertentu dari suatu layanan, Anda dapat melakukannya seperti ini:
sumber
Jika pengontrol Anda ditulis untuk menerima dependensi seperti ini:
maka Anda bisa membuat palsu
someDependency
dalam tes Jasmine seperti ini:sumber
Saya baru-baru ini merilis ngImprovedTesting yang seharusnya membuat pengujian tiruan di AngularJS menjadi lebih mudah.
Untuk menguji 'myService' (dari modul "myApp") dengan fooService dan dependensi barService yang diejek, Anda dapat melakukan hal berikut dalam pengujian Jasmine Anda:
Untuk informasi lebih lanjut tentang ngImprovedTesting, lihat entri blog pengantar: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/
sumber
Saya tahu ini adalah pertanyaan lama tetapi ada cara lain yang lebih mudah, Anda dapat membuat tiruan dan menonaktifkan injeksi asli pada satu fungsi, itu dapat dilakukan dengan menggunakan spyOn pada semua metode. lihat kode di bawah ini.
sumber