Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Angular
Code

Komponen Pengujian dalam Angular Menggunakan Jasmine: Bagian 2, Layanan

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Ilham Saputra (you can also view the original English article)

Final product image
What You'll Be Creating

Ini adalah angsuran kedua dari seri pada pengujian di Angular menggunakan Jasmine. Di bagian pertama dari tutorial, kami menulis tes unit dasar untuk kelas Pastebin dan komponen Pastebin. Tes, yang awalnya gagal, menjadi hijau kemudian.

Ikhtisar

Berikut ini adalah ikhtisar dari apa kita akan kerjakan di dalam bagian kedua dari tutorial.

High level overview of things weve discussed in the previous tutorial and things we will be discussing in this tutorial

Dalam tutorial ini, kita akan:

  • membuat komponen baru dan menulis unit test yang lain
  • menulis tes untuk komponen UI
  • menulis unit tes untuk layanan Pastebin
  • pengujian komponen dengan input dan output
  • pengujian komponen dengan route

Mari kita mulai!

Menambahkan Paste (lanjutan)

Kami sudah setengah jalan melalui proses penulisan tes unit untuk komponen AddPaste. Di sinilah kami tinggalkan di bagian satu dari seri.

Seperti yang disebutkan sebelumnya, kami tidak akan menulis tes UI yang ketat. Sebagai gantinya, kami akan menulis beberapa tes dasar untuk UI dan mencari cara untuk menguji logika komponen.

Tindakan klik dipicu menggunakan metode DebugElement.triggerEventHandler(), yang merupakan bagian dari utilitas pengujian Angular.

Komponen AddPaste pada dasarnya tentang menciptakan paste baru; karenanya, template komponen harus memiliki tombol untuk membuat paste baru. Mengeklik tombol harus memunculkan 'modal window' dengan id 'source-modal' yang seharusnya tetap tersembunyi. Modal window akan dirancang menggunakan Bootstrap; Oleh karena itu, Anda mungkin menemukan banyak kelas CSS di dalam template.

Template untuk komponen add-paste akan terlihat seperti ini:

Tes kedua dan ketiga tidak memberikan informasi apa pun tentang rincian penerapan komponen. Berikut versi revisi add-paste.component.spec.ts.

Tes yang direvisi lebih eksplisit karena mereka mendeskripsikan logika komponen secara sempurna. Inilah komponen AddPaste dan templatenya.

Tes harus tetap gagal karena mata-mata pada addPaste gagal menemukan metode seperti itu di PastebinService. Mari kita kembali ke PastebinService dan menaruh beberapa daging di atasnya.

Menulis tes untuk Layanan

Sebelum kita melanjutkan dengan menulis tes lagi, mari kita tambahkan beberapa kode ke layanan Pastebin.

addPaste() adalah metode layanan untuk membuat paste baru. http.post mengembalikan yang dapat diamati, yang diubah menjadi promise menggunakan metode toPromise(). Respons diubah menjadi format JSON, dan segala pengecualian waktu proses tertangkap dan dilaporkan oleh handleError().

Bukankah kita harus menulis tes untuk layanan, Anda mungkin bertanya? Dan jawabanku pasti ya. Layanan, yang disuntikkan ke komponen Angular melalui Dependensi Injeksi (DI), juga rentan terhadap eror. Selain itu, tes untuk layanan Sudut relatif mudah. Metode di PastebinService seharusnya menyerupai empat operasi CRUD, dengan metode tambahan untuk menangani eror. Metodenya adalah sebagai berikut:

  • handleError()
  • getPastebin()
  • addPaste()
  • updatePaste()
  • deletePaste()

Kami telah menerapkan tiga metode pertama dalam daftar. Mari coba tes tertulis untuk mereka. Inilah blok uraian.

Kami telah menggunakan TestBed.get(PastebinService) untuk menyuntikkan layanan nyata ke dalam pengujian kami.

getPastebin mengembalikan array objek Pastebin. Pengecekan jenis kompilasi-waktu TypeScript tidak dapat digunakan untuk memverifikasi bahwa nilai yang dikembalikan memang merupakan array dari objek Pastebin. Oleh karena itu, kami telah menggunakan Object.getOwnPropertNames() untuk memastikan bahwa kedua objek memiliki nama properti yang sama.

Tes kedua sebagai berikut:

Kedua tes harus lulus. Berikut adalah tes yang tersisa.

Merevisi pastebin.service.ts dengan kode untuk metode updatePaste() dan deletePaste().

Kembali ke komponen

Persyaratan yang tersisa untuk komponen AddPaste adalah sebagai berikut:

  • Menekan tombol Save harus menggunakan metode addPaste() dari Pastebin service.
  • Jika operasi addPaste berhasil, komponen harus memancarkan acara untuk memberi tahu komponen induk.
  • Mengeklik tombol Close harus menghapus id 'source-modal' dari DOM dan memperbarui properti showModal menjadi false.

Karena kasus-kasus pengujian di atas berkaitan dengan modal window, mungkin ada baiknya menggunakan blok deskripsi bertingkat.

Mendeklarasikan semua variabel di root blok menggambarkan adalah praktik yang baik karena dua alasan. Variabel akan dapat diakses di dalam blok deskripsi di mana mereka dinyatakan, dan itu membuat tes lebih mudah dibaca.

Tes di atas menggunakan metode querySelector() untuk menetapkan inputTitle, SelectLanguage, dan textAreaPaste elemen HTML mereka masing-masing (<input>,<select> dan <textArea>). Selanjutnya, nilai-nilai elemen-elemen ini digantikan oleh nilai properti mockPaste. Ini sama dengan pengguna mengisi formulir melalui browser.

element.dispatchEvent(new Event("input")) memicu event input baru untuk membiarkan template mengetahui bahwa nilai dari field input telah berubah. Tes mengharapkan bahwa nilai input harus disebarkan ke properti newPaste komponen.

Menyatakan properti newPaste sebagai berikut:

Dan memperbarui template dengan kode berikut:

Ekstra divs dan kelas untuk modal window Bootstrap. [(ngModel)] adalah perintah Angular yang mengimplementasikan pengikatan data dua arah. (click) = "onClose ()" dan (click) = "onSave ()" adalah contoh teknik event binding yang digunakan untuk mengikat event klik ke metode dalam komponen. Anda dapat membaca lebih lanjut tentang teknik pengikatan data yang berbeda di Panduan Syntax Template resmi Angular.

Jika Anda mengalami Kesalahan Parse Template, itu karena Anda belum mengimpor FormsModule ke dalam AppComponent.

Mari tambahkan lebih banyak spesifikasi untuk pengujian kami.

component.onSave() analog dengan pemanggilan triggerEventHandler() pada elemen tombol Save. Karena kami telah menambahkan UI untuk tombol tersebut, memanggil component.save() terdengar lebih berarti. Pernyataan yang diharapkan memeriksa apakah ada panggilan yang dilakukan ke mata-mata itu. Berikut ini versi terakhir dari komponen AddPaste.

Jika operasi onSave berhasil, komponen harus memancarkan peristiwa yang menandakan komponen induk (komponen Pastebin) untuk memperbarui view. addPasteSuccess, yang merupakan properti acara yang dihiasi dengan penghias @Output, melayani tujuan ini.

Menguji komponen yang memancarkan event keluaran itu mudah.

Tes ini berlangganan properti addPasteSuccess seperti yang dilakukan oleh komponen induk. Harapan pada akhirnya akan membenarkan hal ini. Pekerjaan kami pada komponen AddPaste dilakukan.

Hapus tanda komentar baris ini di pastebin.component.html:

Dan memperbarui pastebin.component.ts dengan kode di bawah ini.

Jika Anda mengalami kesalahan, itu karena Anda belum menyatakan komponen AddPaste dalam file spesifikasi komponen Pastebin. Bukankah lebih bagus lagi jika kita dapat menyatakan semua yang diperlukan pengujian kami di satu tempat dan mengimpornya ke dalam pengujian kami? Untuk mewujudkan hal ini, kita dapat mengimpor AppModule ke dalam pengujian kami atau membuat Modul baru untuk pengujian kami. Buat file baru dan beri nama app-testing-module.ts:

Sekarang Anda dapat mengganti:

dengan:

Metadata yang menentukan providers dan declarations telah menghilang dan sebaliknya, AppTestingModule mendapat diimpor. Itu rapi! TestBed.configureTestingModule() terlihat lebih ramping dari sebelumnya.

View, Edit, and Delete Paste

Komponen ViewPaste menangani logika untuk melihat, mengedit, dan menghapus paste. Desain komponen ini mirip dengan apa yang kami lakukan dengan komponen AddPaste.

Mock design of the ViewPasteComponent in edit mode
Mode edit
Mock design of the ViewPasteComponent in view mode
Mode view

Tujuan komponen ViewPaste tercantum di bawah ini:

  • Komponen yang template harus memiliki sebuah tombol yang bernama View Paste.
  • Mengklik tombol View Paste harus menampilkan jendela modal dengan id 'source-modal'.
  • Data paste harus menyebar dari komponen parent ke komponen child dan harus ditampilkan di dalam modal window.
  • Menekan tombol edit harus mengatur component.editEnabled ke true (editEnabled digunakan untuk beralih antara mode edit dan mode view)
  • Mengklik tombol Save harus memanggil metode updatePaste() Layanan Pastebin.
  • Klik pada tombol Delete harus memanggil metode deletePaste() Layanan Pastebin.
  • Pembaruan dan penghapusan operasi yang berhasil harus memancarkan event untuk memberi tahu komponen parent dari setiap perubahan pada komponen child.

Mari kita mulai! Dua spesifikasi pertama identik dengan pengujian yang kami tulis untuk komponen AddPaste sebelumnya.

Mirip dengan apa yang kami lakukan sebelumnya, kami akan membuat blok deskripsi baru dan menempatkan sisa spesifikasi di dalamnya. Nesting mendeskripsikan blok dengan cara ini membuat file spek lebih mudah dibaca dan keberadaan fungsi mendeskripsi lebih bermakna.

Blok deskripsi bersarang akan memiliki fungsi beforeEach() di mana kami akan menginisialisasi dua mata-mata, satu untuk metode updatePaste() dan yang lainnya untuk metode deletePaste(). Jangan lupa untuk membuat objek mockPaste karena tes kami bergantung padanya.

Berikut adalah tes.

Pengujian mengasumsikan bahwa komponen memiliki properti paste yang menerima input dari komponen parent. Sebelumnya, kami melihat contoh bagaimana event yang dipancarkan dari komponen child dapat diuji tanpa harus memasukkan logika komponen host ke dalam pengujian kami. Demikian pula, untuk menguji properti input, lebih mudah melakukannya dengan menyetel properti ke objek tiruan dan mengharapkan nilai objek tiruan muncul di kode HTML.

Modal window akan memiliki banyak tombol, dan itu bukan ide yang buruk untuk menulis spec untuk menjamin bahwa tombol tersedia di template.

Mari perbaiki tes yang gagal sebelum melakukan tes yang lebih rumit.

Mampu melihat paste saja tidak cukup. Komponen ini juga bertanggung jawab untuk mengedit, memperbarui, dan menghapus paste. Komponen harus memiliki properti editEnabled, yang akan disetel ke true ketika pengguna mengklik tombol Edit paste.

Tambahkan editEnabled=true; metode onEdit() untuk menghapus pernyataan pertama ekspektasi.

Template di bawah ini menggunakan direktif ngIf untuk beralih antara mode tampilan dan mode edit. <ng-container> adalah wadah logika yang digunakan untuk mengelompokkan beberapa elemen atau node.

Komponen harus memiliki dua Output() event emitters, satu untuk properti updatePasteSuccess dan yang lainnya untuk deletePasteSuccess. Tes di bawah ini memverifikasi hal-hal berikut:

  1. Template komponen yang menerima input.
  2. Masukan template terikat untuk properti paste komponen.
  3. Jika operasi update berhasil, updatePasteSuccess memancarkan sebuah event dengan paste diperbarui.

Perbedaan jelas antara tes ini dan yang sebelumnya adalah penggunaan fungsi fakeAsync. fakeAsync dapat dibandingkan dengan async karena kedua fungsi tersebut digunakan untuk menjalankan pengujian dalam zona pengujian asynchronous. Namun, fakeAsync membuat tampilan tes Anda terlihat lebih sinkron.

Metode tick() menggantikan fixture.whenStable().then(), dan kode lebih mudah dibaca dari perspektif pengembang. Jangan lupa untuk mengimpor fakeAsync dan tanda dari @angular/core/testing.

Akhirnya, berikut adalah spesifikasi untuk menghapus paste.

Kami hampir selesai dengan komponen. Berikut ini adalah rancangan akhir dari komponen ViewPaste.

Komponen induk (pastebin.component.ts) perlu diperbarui dengan metode untuk menangani peristiwa yang dipancarkan oleh komponen child.

Berikut adalah pastebin.component.html Diperbarui:

Mengatur Route

Untuk membuat aplikasi yang dirutekan, kami memerlukan beberapa komponen stok lagi sehingga kami dapat membuat rute sederhana yang mengarah ke komponen ini. Saya telah membuat komponen About dan komponen Contact sehingga kami dapat menempatkannya di dalam bilah navigasi. AppComponent akan menahan logika untuk rute. Kami akan menulis tes untuk rute setelah kami selesai dengan mereka.

Pertama, impor RouterModule dan Routes ke AppModule (dan AppTestingModule).

Selanjutnya, tentukan rute Anda dan berikan definisi rute ke metode RouterModule.forRoot.

Setiap perubahan yang dilakukan untuk AppModule juga harus dilakukan ke AppTestingModule. Tetapi jika Anda mengalami eror No base href set saat menjalankan pengujian, tambahkan baris berikut ke array providers AppTestingModule Anda.

Sekarang tambahkan kode berikut untuk app.component.html.

routerLink adalah petunjuk yang digunakan untuk mengikat elemen HTML dengan route. Kami telah menggunakannya dengan tag anchor HTML di sini. RouterOutlet adalah petunjuk lain yang menandai tempat di template di mana tampilan router harus ditampilkan.

Menguji route agak sulit karena melibatkan lebih banyak interaksi UI. Inilah tes yang memeriksa apakah tautan berfungsi baik.

Jika semuanya berjalan dengan baik, Anda akan melihat sesuatu seperti ini.

Screenshot of Karma test runner on Chrome displaying the final test results

Sentuhan Akhir

Tambahkan desain Bootstrap yang cantik ke proyek Anda, dan sajikan proyek Anda jika Anda belum melakukannya.

Ringkasan

Kami menulis aplikasi lengkap dari awal dalam lingkungan yang digerakkan oleh pengujian. Bukankah itu sesuatu? Dalam tutorial ini, kita belajar:

  • cara mendesain komponen menggunakan pendekatan tes pertama
  • bagaimana menulis tes unit dan tes UI dasar untuk komponen
  • tentang utilitas pengujian Angular dan bagaimana menggabungkannya ke dalam pengujian kami
  • tentang menggunakan async() dan fakeAsync() untuk menjalankan pengujian asynchronous
  • dasar-dasar routing dalam tes Angular dan menulis untuk route

Saya harap Anda menikmati alur kerja TDD. Silakan hubungi melalui komentar dan beri tahu kami pendapat Anda!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.