JavaScript adalah bahasa tipe yang dinamis, yang memberinya kemampuan kinerja yang kuat, tetapi juga membuat kompiler hampir tidak mungkin untuk memberikan bantuan kepada pengembang. Untuk alasan ini, kami merasa bahwa menulis kode JavaScript harus memiliki serangkaian tes yang kuat dan lengkap. Angular memiliki banyak fitur yang memudahkan kami untuk menguji aplikasi kami. Kita seharusnya tidak memiliki alasan untuk tidak menulis tes (ini dia ...).
1. Ini semua tentang tidak mencampur masalah (ini semua tentang menghindari hubungan kode menjadi rumit ...)
Pengujian unit, seperti namanya, adalah tentang menguji satu "unit" tunggal. Pengujian unit berusaha untuk menjawab pertanyaan -pertanyaan ini: Apakah saya sudah benar dalam pertimbangan logika saya? Apakah hasilnya diperoleh dengan metode penyortiran benar? Untuk menjawab pertanyaan -pertanyaan ini, sangat penting untuk memisahkannya. Ini karena ketika kami menguji metode penyortiran, kami tidak ingin peduli dengan fragmen terkait lainnya, seperti elemen DOM atau memulai permintaan XHR untuk mendapatkan data, dll. Jelas, biasanya sulit untuk menyebut fungsi secara terpisah dalam proyek tipikal. Alasan untuk masalah ini adalah bahwa pengembang sering membuat hubungan rumit dan akhirnya membuat cuplikan terlihat seperti dapat melakukan segalanya. Ini mendapatkan data melalui XHR, mengurutkan data, dan kemudian memanipulasi DOM. Bersama dengan Angular kita dapat menulis kode yang lebih mudah dengan lebih mudah, jadi Angular memberi kita injeksi ketergantungan XHR (yang dapat kita simulasikan) dan Angular juga membuat abstraksi yang memungkinkan kita untuk mengurutkan model tanpa memanipulasi DOM. Jadi, pada akhirnya, kita dapat dengan mudah menulis metode penyortiran, dan kemudian membuat set data melalui case uji untuk metode penyortiran yang akan digunakan saat menguji, dan kemudian menentukan apakah model hasil memenuhi ekspektasi. Tes tidak memerlukan menunggu XHR untuk membuat DOM yang sesuai dan menentukan apakah fungsi mengoperasikan DOM dengan benar. Gagasan inti dari Angular mencakup pengujian kode, tetapi juga mengharuskan kita untuk melakukan hal yang benar. Angular berkomitmen untuk menyederhanakan cara untuk melakukan hal yang benar, tetapi Angular bukanlah sihir, yang berarti bahwa kita mungkin berakhir dengan aplikasi yang tidak dapat diperkirakan jika kita tidak mengikuti poin berikut.
1. Suntikan ketergantungan
Ada banyak cara untuk mendapatkan sumber daya ketergantungan: 1) Kita dapat menggunakan operator baru; 2) kami menggunakan metode terkenal yang disebut "Global Singleton"; 3) kita dapat memintanya dari Layanan Registri (tetapi bagaimana kami mendapatkan registri? Anda dapat memeriksa bab -bab berikut); 4) Kita bisa mengharapkannya akan dilewati.
Dari metode yang tercantum di atas, hanya yang terakhir yang dapat diuji, mari kita lihat mengapa:
1) Menggunakan operator baru
Pada dasarnya tidak ada kesalahan saat menggunakan operator baru, tetapi masalahnya adalah bahwa memanggil konstruktor melalui will baru secara permanen mengikat penelepon ke jenis. Misalnya, kami mencoba untuk membuat objek XHR sehingga kami bisa mendapatkan beberapa data dari server.
function myclass () {this.deWork = function () {var xhr = new xrh (); xhr.open (metode, url, true); xhr.onreadystatechange = function () {...}; xhr.send (); }}Masalahnya adalah bahwa ketika menguji, kita biasanya perlu instantiate XHR virtual yang dapat mengembalikan data uji atau kesalahan jaringan. Dengan menelepon XHR baru (), kami secara permanen mengikat XHR asli, dan tidak ada cara yang baik untuk menggantinya. Tentu saja, ada obat yang buruk dan ada banyak alasan untuk membuktikan bahwa itu adalah ide yang buruk:
var oldxhr = xhr; xhr = mockxhr baru () {}; myclass.dowork (); // menilai apakah mockxhr memanggil xhr = oldxhr melalui parameter normal; // jika Anda lupa langkah ini, mudah untuk menyebabkan hal -hal menyedihkan.2) Pencarian Global
Cara lain untuk menyelesaikan masalah adalah dengan mendapatkan sumber daya ketergantungan di tempat yang terkenal.
function myclass () {this.deWork = function () {global.xhr ({...}); };}Tanpa membuat instance dari objek dependen baru, masalahnya pada dasarnya sama dengan yang baru, dan tidak ada cara yang baik untuk mencegat panggilan global.xhr saat menguji. Masalah paling mendasar dengan pengujian adalah bahwa variabel global perlu diubah untuk memanggil metode virtual dan dimodifikasi. Untuk mempelajari lebih lanjut tentang kerugiannya, kunjungi di sini: http://misko.hevery.com/code-reviewers-guide/flaw-rittle-global-state-singletons/
Kode di atas sulit untuk diuji, jadi kita harus memodifikasi keadaan global:
var oldxhr = global.xhr; global.xhr = fungsi mockxhr () {...}; var myclass = myclass baru (); // menilai apakah mockxhr menyebut global.xhr = oldxhr melalui parameter normal; // Jika Anda lupa langkah ini, mudah menyebabkan hal -hal sedih.3) Registri Layanan
Memiliki registri dengan semua layanan tampaknya menyelesaikan masalah, dan kemudian mengganti layanan yang diperlukan dalam kode uji.
function myclass () {var serviceregistry = ???; this.deWork = function () {var xhr = serviceeregistry.get ("xhr"); …};}Tapi dari mana asalnya serviceregistry itu? Jika itu: * New-ed UP, tes tidak memiliki kesempatan untuk mengatur ulang layanan untuk pengujian * pencarian global, maka layanan yang dikembalikan juga global (tetapi pengaturan ulang lebih mudah, karena hanya ada satu variabel global yang akan diatur ulang) (teks di belakang sini sama seperti yang dikocok ... Saya tidak mengerti)
Menurut metode ini, ubah kelas di atas dengan metode berikut:
var oldservicelocator = global.servicelocator; global.servicelocator.set ('xhr', fungsi mockxhr () {}); var myclass = myclass baru (); myclass.dowork (); // menilai apakah mockxhr memanggil global.servicelocator = oldservicoror; // Jika Anda lupa langkah ini, mudah untuk menyebabkan hal -hal menyedihkan.4) Meneruskan ketergantungan
Akhirnya, sumber daya ketergantungan dapat dilewati.
function myclass (xhr) {this.deWork = function () {xhr ({...}); };}Ini adalah metode yang disukai, karena kode tidak perlu memperhatikan dari mana XHR berasal, juga tidak peduli siapa yang menciptakan XHR masuk. Oleh karena itu, pencipta kelas dapat dikodekan secara terpisah dari konsumen kelas, yang memisahkan tanggung jawab penciptaan dari logika, yang merupakan ikhtisar injeksi ketergantungan.
Kelas ini mudah diuji, dan kita dapat menulisnya seperti ini dalam tes:
fungsi xhrmock (args) {...} var myclass = myclass baru (xhrmock); myclass.dowrok (); // buat beberapa penilaian ... melalui kode pengujian ini, kita dapat menyadari bahwa tidak ada variabel global yang rusak.Injeksi ketergantungan (//www.vevb.com/article/91775.htm) disertakan dengan Angular, kode yang ditulis dengan cara ini membuatnya lebih mudah untuk menulis kode uji. Jika kami ingin menulis kode yang sangat mudah diuji, sebaiknya kami gunakan.
2. Pengontrol
Logika membuat setiap aplikasi unik, dan itulah yang ingin kami uji. Jika logika kami dicampur dengan operasi DOM, ini akan sulit untuk diuji seperti contoh berikut:
function passwordController () {// Dapatkan referensi ke objek DOM var msg = $ ('. Ex1 span'); var input = $ ('. Ex1 input'); kekuatan var; this.grade = function () {msg.removeclass (kekuatan); var pwd = input.val (); Password.text (PWD); if (pwd.length> 8) {kekuatan = 'kuat'; } lain jika (pwd.length> 3) {kekuatan = 'medium'; } else {kekuatan = 'lemah'; } msg.addclass (kekuatan) .text (kekuatan); }}Kode di atas akan mengalami masalah saat menguji karena mengharuskan kita untuk memiliki DOM yang benar saat menjalankan tes. Kode tes akan sebagai berikut:
var input = $ ('<input type = "text"/>'); var span = $ ('<span>'); $ ('body'). html ('<verv>'). find ('div'). append (input). lampai (span); var pc = baru PasswordController (); input.val ('abc'); pc.grade (); harapkan (span.text ()). Toequal ('lemah'); $ ('body'). Html ('');Dalam sudut, pengontrol secara ketat memisahkan logika operasi DOM, yang akan sangat mengurangi kesulitan menulis kasus uji. Lihatlah contoh berikut:
fungsi kata sandicntrl ($ scope) {$ scope.password = ''; $ scope.grade = function () {var size = $ scope.password.length; if (size> 8) {$ scope.strength = 'strong'; } lain jika (ukuran> 3) {$ scope.strength = 'medium'; } else {$ scope.strength = 'lemah'; }};}Kode uji langsung:
var pc = New PasswordController ($ scope); pc.password ('abc'); pc.grade (); harapkan ($ scope.strength) .toequal ('lemah');Perlu dicatat bahwa kode uji tidak hanya lebih terputus, tetapi lebih mudah dilacak. Kami selalu mengatakan bahwa kasus tes menceritakan kisah, bukan menilai hal -hal lain yang tidak relevan.
3. Filter
Filter (http://docs.angularjs.org/api/ng.$filter) digunakan untuk mengonversi data menjadi format yang ramah pengguna. Mereka penting karena mereka memisahkan tanggung jawab mengkonversi format dari logika aplikasi, lebih jauh menyederhanakan logika aplikasi.
mymodule.filter ('length', function () {return function (text) {return (''+(Text || '' ')). Length;}}); var length = $ filter (' length '); harapkan (panjang (null)). Toequal (0); length (' abc ')). Toequal (3)).4. Arahan
5. Mocks
6. Isolasi Negara Global
7. Cara pengujian yang disukai
8. JavaScriptTestDriver
9. Jasmine
10. Proyek Sampel
Kami akan terus memperbarui artikel terkait di masa depan. Terima kasih atas dukungan Anda untuk situs ini!