Saya baru dalam pengujian unit, dan saya terus menerus mendengar kata-kata 'benda tiruan' yang sering dilontarkan. Dalam istilah awam, dapatkah seseorang menjelaskan benda tiruan apa, dan apa yang biasanya mereka gunakan saat menulis tes unit?
unit-testing
mocking
agentbanks217
sumber
sumber
Jawaban:
Karena Anda mengatakan Anda baru dalam pengujian unit dan meminta objek tiruan dalam "istilah awam", saya akan mencoba contoh awam.
Pengujian Unit
Bayangkan pengujian unit untuk sistem ini:
Secara umum mudah membayangkan pengujian komponen tingkat rendah seperti
cook
:Penguji hanya memesan hidangan yang berbeda dan memverifikasi juru masak mengembalikan hidangan yang benar untuk setiap pesanan.
Lebih sulit untuk menguji komponen tengah, seperti pelayan, yang memanfaatkan perilaku komponen lain. Penguji naif mungkin menguji komponen pelayan dengan cara yang sama seperti kami menguji komponen juru masak:
Penguji akan memesan hidangan yang berbeda dan memastikan pelayan mengembalikan hidangan yang benar. Sayangnya, itu berarti bahwa pengujian komponen pelayan ini mungkin tergantung pada perilaku komponen koki yang benar. Ketergantungan ini bahkan lebih buruk jika komponen koki memiliki karakteristik uji-tidak ramah, seperti perilaku non-deterministik (menu termasuk kejutan koki sebagai hidangan), banyak ketergantungan (koki tidak akan memasak tanpa seluruh stafnya), atau banyak sumber daya (beberapa hidangan membutuhkan bahan-bahan mahal atau membutuhkan waktu satu jam untuk memasak).
Karena ini adalah tes pelayan, idealnya, kami ingin menguji hanya pelayan, bukan koki. Secara khusus, kami ingin memastikan pelayan menyampaikan pesanan pelanggan kepada juru masak dengan benar dan mengirimkan makanan juru masak kepada pelanggan dengan benar.
Pengujian unit berarti menguji unit secara independen, jadi pendekatan yang lebih baik adalah mengisolasi komponen yang diuji (pelayan) menggunakan apa yang disebut Fowler sebagai uji ganda (boneka, bertopik, palsu, pura-pura) .
Di sini, test cook adalah "bersekongkol" dengan driver tes. Idealnya, sistem yang diuji dirancang sehingga juru masak uji dapat dengan mudah diganti ( disuntikkan ) untuk bekerja dengan pelayan tanpa mengubah kode produksi (misalnya tanpa mengubah kode pelayan).
Objek Mock
Sekarang, juru masak uji (tes ganda) dapat diimplementasikan dengan berbagai cara:
Lihat artikel Fowler untuk lebih spesifik tentang palsu vs bertopik vs tiruan vs boneka , tetapi untuk sekarang, mari kita fokus pada juru masak tiruan.
Sebagian besar unit menguji komponen pelayan berfokus pada bagaimana pelayan berinteraksi dengan komponen koki. Pendekatan berbasis tiruan berfokus pada menentukan secara lengkap apa interaksi yang benar dan mendeteksi ketika berjalan serba salah.
Objek tiruan mengetahui terlebih dahulu apa yang seharusnya terjadi selama pengujian (mis. Panggilan metodenya mana yang akan dipanggil, dll.) Dan objek tiruan tahu bagaimana seharusnya bereaksi (misalnya apa nilai pengembalian yang diberikan). Mock akan menunjukkan apakah apa yang sebenarnya terjadi berbeda dari apa yang seharusnya terjadi. Objek tiruan kustom dapat dibuat dari awal untuk setiap kasus uji untuk mengeksekusi perilaku yang diharapkan untuk kasus uji tersebut, tetapi kerangka kerja mengejek berusaha untuk memungkinkan spesifikasi perilaku seperti itu secara jelas dan mudah ditunjukkan secara langsung dalam kasus uji.
Percakapan seputar tes berbasis mock mungkin terlihat seperti ini:
Tetapi karena pelayan kami baru, inilah yang bisa terjadi:
atau
Mungkin sulit untuk secara jelas melihat perbedaan antara benda tiruan dan bertopik tanpa contoh berbasis rintisan yang kontras untuk pergi dengan ini, tetapi jawaban ini sudah terlalu lama :-)
Juga perhatikan bahwa ini adalah contoh yang cukup sederhana dan bahwa kerangka kerja mengejek memungkinkan untuk beberapa spesifikasi yang cukup canggih dari perilaku yang diharapkan dari komponen untuk mendukung tes komprehensif. Ada banyak materi tentang objek tiruan dan kerangka kerja mengejek untuk informasi lebih lanjut.
sumber
Objek Mock adalah objek yang menggantikan objek nyata. Dalam pemrograman berorientasi objek, objek tiruan adalah objek simulasi yang meniru perilaku objek nyata dengan cara yang terkontrol.
Seorang programmer komputer biasanya membuat objek tiruan untuk menguji perilaku beberapa objek lain, dengan cara yang sama seperti seorang perancang mobil menggunakan tiruan uji tabrakan untuk mensimulasikan perilaku dinamis manusia dalam dampak kendaraan.
http://en.wikipedia.org/wiki/Mock_object
Objek tiruan memungkinkan Anda mengatur skenario pengujian tanpa membawa sumber daya besar dan sulit seperti database. Alih-alih memanggil basis data untuk pengujian, Anda dapat mensimulasikan basis data Anda menggunakan objek tiruan dalam pengujian unit Anda. Ini membebaskan Anda dari beban harus mengatur dan meruntuhkan database nyata, hanya untuk menguji satu metode di kelas Anda.
Kata "Mock" kadang-kadang keliru digunakan secara bergantian dengan "Stub." Perbedaan antara kedua kata tersebut dijelaskan di sini. Pada dasarnya, tiruan adalah objek rintisan yang juga mencakup harapan (yaitu "pernyataan") untuk perilaku yang tepat dari objek / metode yang diuji.
Sebagai contoh:
Perhatikan bahwa objek
warehouse
danmailer
tiruan diprogram dengan hasil yang diharapkan.sumber
Benda tiruan adalah benda tiruan yang meniru perilaku benda nyata. Biasanya Anda menulis objek tiruan jika:
sumber
Objek Mock adalah salah satu jenis Tes Ganda . Anda menggunakan mockobjects untuk menguji dan memverifikasi protokol / interaksi kelas yang diuji dengan kelas lain.
Biasanya Anda akan jenis 'program' atau 'catatan' harapan: metode panggilan yang Anda harapkan kelas Anda lakukan ke objek yang mendasarinya.
Katakanlah misalnya kita sedang menguji metode layanan untuk memperbarui bidang dalam Widget. Dan itu dalam arsitektur Anda ada WidgetDAO yang berkaitan dengan database. Berbicara dengan database lambat dan pengaturannya dan pembersihan setelah itu rumit, jadi kami akan mengejek WidgetDao.
mari kita pikirkan apa yang harus dilakukan oleh layanan: itu harus mendapatkan Widget dari database, melakukan sesuatu dengannya dan menyimpannya lagi.
Jadi dalam bahasa pseudo dengan pseudo-mock library kita akan memiliki sesuatu seperti:
Dengan cara ini kita dapat dengan mudah menguji pengembangan drive dari kelas yang bergantung pada kelas lain.
sumber
Saya sangat merekomendasikan artikel hebat dari Martin Fowler yang menjelaskan apa sebenarnya ejekan itu dan bagaimana perbedaannya dengan bertopik.
sumber
Saat unit menguji beberapa bagian dari program komputer, Anda idealnya hanya ingin menguji perilaku bagian tertentu itu.
Sebagai contoh, lihat pseudo-code di bawah ini dari bagian imajiner dari program yang menggunakan program lain untuk memanggil print sesuatu:
Jika Anda menguji ini, Anda terutama ingin menguji bagian yang melihat apakah pengguna adalah Fred atau tidak. Anda tidak benar-benar ingin menguji
Printer
bagian dari semuanya. Itu akan menjadi ujian lain.Ini adalah di mana benda Mock datang. Mereka berpura-pura menjadi jenis lain hal. Dalam hal ini Anda akan menggunakan Mock
Printer
sehingga akan bertindak seperti printer sungguhan, tetapi tidak akan melakukan hal-hal yang tidak nyaman seperti mencetak.Ada beberapa jenis objek pura-pura yang bisa Anda gunakan yang bukan Mock. Hal utama yang membuat Mocks Mocks adalah bahwa mereka dapat dikonfigurasi dengan perilaku dan harapan.
Ekspektasi memungkinkan Mock Anda meningkatkan kesalahan saat digunakan secara tidak benar. Jadi, dalam contoh di atas, Anda dapat memastikan bahwa Printer dipanggil dengan HelloFred di dalam case test "user is Fred". Jika itu tidak terjadi, Mock Anda dapat memperingatkan Anda.
Perilaku di Mocks berarti bahwa, misalnya, kode Anda melakukan sesuatu seperti:
Sekarang Anda ingin menguji apa yang kode Anda lakukan ketika Printer dipanggil dan mengembalikan SaidHello, sehingga Anda dapat mengatur Mock untuk mengembalikan SaidHello ketika dipanggil dengan HelloFred.
Salah satu sumber yang bagus untuk hal ini adalah Martin Fowlers memposting Mocks Aron't Stubs
sumber
Objek tiruan dan rintisan adalah bagian penting dari pengujian unit. Bahkan mereka jauh untuk memastikan Anda menguji unit , bukan kelompok unit.
Singkatnya, Anda menggunakan bertopik untuk mematahkan ketergantungan (System Under Test) SUT pada objek dan tiruan lain untuk melakukan itu dan memverifikasi bahwa SUT disebut metode / properti tertentu pada dependensi. Ini kembali ke prinsip dasar pengujian unit - bahwa pengujian harus mudah dibaca, cepat dan tidak memerlukan konfigurasi, yang mungkin menyiratkan semua kelas nyata.
Secara umum, Anda dapat memiliki lebih dari satu rintisan dalam ujian Anda, tetapi Anda seharusnya hanya memiliki satu tiruan. Ini karena tujuan mock adalah untuk memverifikasi perilaku dan pengujian Anda seharusnya hanya menguji satu hal.
Skenario sederhana menggunakan C # dan Moq:
Dalam contoh di atas saya menggunakan Moq untuk menunjukkan stub dan ejekan. Moq menggunakan kelas yang sama untuk keduanya -
Mock<T>
yang membuatnya sedikit membingungkan. Apapun, saat runtime, tes akan gagal jikaoutput.Write
tidak dipanggil dengan dataparameter
, sedangkan kegagalan untuk meneleponinput.Read()
tidak akan gagal itu.sumber
Seperti jawaban lain yang disarankan melalui tautan ke " Mocks Aron't Stubs ", mock adalah bentuk "test double" untuk digunakan sebagai pengganti objek nyata. Apa yang membuatnya berbeda dari bentuk tes ganda lainnya, seperti objek rintisan, adalah bahwa tes ganda lainnya menawarkan verifikasi keadaan (dan simulasi opsional) sedangkan tiruan menawarkan verifikasi perilaku (dan simulasi opsional).
Dengan sebuah rintisan, Anda dapat memanggil beberapa metode pada rintisan dalam urutan apa pun (atau bahkan secara repitious) dan menentukan keberhasilan jika rintisan tersebut telah mengambil nilai atau keadaan yang Anda maksudkan. Sebaliknya, objek tiruan mengharapkan fungsi yang sangat spesifik untuk dipanggil, dalam urutan tertentu, dan bahkan beberapa kali tertentu. Tes dengan objek tiruan akan dianggap "gagal" hanya karena metode dipanggil dalam urutan atau hitungan yang berbeda - bahkan jika objek tiruan memiliki keadaan yang benar ketika tes berakhir!
Dengan cara ini, objek tiruan sering dianggap lebih erat digabungkan ke kode SUT daripada objek rintisan. Itu bisa menjadi hal yang baik atau buruk, tergantung pada apa yang Anda coba verifikasi.
sumber
Bagian dari titik menggunakan objek tiruan adalah bahwa mereka tidak harus benar-benar diimplementasikan sesuai dengan spesifikasi. Mereka hanya bisa memberikan tanggapan bodoh. Misalnya jika Anda harus mengimplementasikan komponen A dan B, dan keduanya "memanggil" (berinteraksi satu sama lain), maka Anda tidak dapat menguji A sampai B diimplementasikan, dan sebaliknya. Dalam pengembangan uji coba, ini adalah masalah. Jadi Anda membuat mock ( "bodoh") obyek untuk A dan B, yang sangat sederhana, tetapi mereka memberikan beberapa jenis respon ketika mereka berinteraksi dengan. Dengan begitu, Anda bisa menerapkan dan menguji A menggunakan objek tiruan untuk B.
sumber
Untuk php dan phpunit dijelaskan dengan baik dalam phpunit documentaion. Lihat disini dokumentasi phpunit
Dalam kata sederhana objek mengejek hanyalah objek tiruan dari objek asli Anda dan mengembalikan nilai kembalinya, nilai pengembalian ini dapat digunakan di kelas uji
sumber
Ini adalah salah satu perspektif utama dari tes unit. ya, Anda mencoba menguji unit kode tunggal Anda dan hasil pengujian Anda seharusnya tidak relevan dengan perilaku kacang atau objek lainnya. jadi Anda harus mengejeknya dengan menggunakan benda-benda Mock dengan beberapa respons yang disederhanakan.
sumber