Saya telah membaca berbagai artikel tentang mengejek dan tidak melakukan pengujian, termasuk Martin Fowler's Mocks Aron't Stubs , tetapi masih tidak mengerti perbedaannya.
963
Saya telah membaca berbagai artikel tentang mengejek dan tidak melakukan pengujian, termasuk Martin Fowler's Mocks Aron't Stubs , tetapi masih tidak mengerti perbedaannya.
Jawaban:
Rintisan
Saya percaya perbedaan terbesar adalah bahwa rintisan yang telah Anda tulis dengan perilaku yang telah ditentukan. Jadi Anda akan memiliki kelas yang mengimplementasikan dependensi (kelas abstrak atau antarmuka yang paling mungkin) Anda berpura-pura untuk tujuan pengujian dan metode hanya akan terhapus dengan tanggapan yang ditetapkan. Mereka tidak akan melakukan sesuatu yang mewah dan Anda akan sudah menulis kode stubbed untuk itu di luar ujian Anda.
Mengejek
Mock adalah sesuatu yang sebagai bagian dari pengujian Anda, Anda harus mengatur dengan harapan Anda. Mock tidak diatur dengan cara yang telah ditentukan sehingga Anda memiliki kode yang melakukannya dalam pengujian Anda. Mengolok-olok dengan cara ditentukan pada saat runtime karena kode yang menetapkan harapan harus dijalankan sebelum mereka melakukan apa pun.
Perbedaan antara Mocks dan Stubs
Tes yang ditulis dengan mengejek biasanya mengikuti
initialize -> set expectations -> exercise -> verify
pola pengujian. Sementara rintisan pra-tertulis akan mengikutiinitialize -> exercise -> verify
.Kesamaan antara Mocks dan Rintisan
Tujuan keduanya adalah untuk menghilangkan pengujian semua dependensi kelas atau fungsi sehingga tes Anda lebih fokus dan lebih sederhana dalam apa yang mereka coba buktikan.
sumber
Kata pengantar
Ada beberapa definisi objek, yang tidak nyata. Istilah umum adalah tes ganda . Istilah ini meliputi: dummy , fake , stub , mock .
Referensi
Menurut artikel Martin Fowler :
Gaya
Mengejek vs bertopik = Pengujian perilaku vs pengujian Negara
Prinsip
Menurut prinsip Uji hanya satu hal per tes , mungkin ada beberapa bertopik dalam satu tes, tetapi umumnya hanya ada satu ejekan.
Lingkaran kehidupan
Tes siklus hidup dengan bertopik:
Tes siklus hidup dengan mengolok-olok:
Ringkasan
Kedua pengujian mengejek dan bertopik memberikan jawaban untuk pertanyaan: Apa hasilnya?
Pengujian dengan mengolok-olok juga tertarik pada: Bagaimana hasilnya telah dicapai?
sumber
Rintisan adalah objek palsu sederhana. Itu hanya memastikan tes berjalan lancar.
Mock adalah rintisan yang lebih cerdas. Anda memverifikasi tes Anda melewati itu.
sumber
Berikut adalah deskripsi masing-masing yang diikuti dengan sampel dunia nyata.
Dummy - hanya nilai palsu untuk memuaskan
API
.Palsu - buat implementasi tes kelas yang mungkin memiliki ketergantungan pada beberapa infrastruktur eksternal. (Ini adalah praktik yang baik bahwa unit test Anda TIDAK benar-benar berinteraksi dengan infrastruktur eksternal.)
Stub - menimpa metode untuk mengembalikan nilai-nilai hard-coded, juga disebut sebagai
state-based
.Mengejek - sangat mirip dengan
Stub
tetapiinteraction-based
bukan berbasis negara. Ini berarti Anda tidak mengharapkan dariMock
untuk mengembalikan nilai, tetapi untuk berasumsi bahwa urutan tertentu dari pemanggilan metode dilakukan.Stubs
danMocks
sebenarnya adalah sub-tipe dariMock
, keduanya menukar implementasi nyata dengan implementasi tes, tetapi untuk alasan yang berbeda dan spesifik.sumber
Dalam kursus codeschool.com , Pengujian Rails untuk Zombies , mereka memberikan definisi persyaratan:
Rintisan
Mengejek
Jadi seperti yang dijelaskan Sean Copenhaver dalam jawabannya, perbedaannya adalah bahwa mengejek menetapkan harapan (yaitu membuat pernyataan, tentang apakah atau bagaimana mereka dipanggil).
sumber
Rintisan bertopik jangan gagal tes Anda, mock bisa.
sumber
Saya pikir jawaban yang paling sederhana dan jelas tentang pertanyaan ini diberikan dari Roy Osherove dalam bukunya The art of Unit Testing (halaman 85)
Itu berarti jika Anda membuat pernyataan palsu, itu berarti Anda menggunakan palsu sebagai tiruan, jika Anda menggunakan palsu hanya untuk menjalankan tes tanpa pernyataan di atasnya Anda menggunakan palsu sebagai rintisan.
sumber
Membaca semua penjelasan di atas, izinkan saya mencoba untuk menyingkat:
sumber
Mock hanya menguji perilaku, memastikan metode tertentu dipanggil. Stub adalah versi yang dapat diuji (per se) dari objek tertentu.
Apa maksud Anda cara Apple?
sumber
Jika Anda membandingkannya dengan debugging:
sumber
Menggunakan model mental benar-benar membantu saya memahami ini, daripada semua penjelasan dan artikel, yang tidak cukup "meresap".
Bayangkan anak Anda memiliki piring kaca di atas meja dan dia mulai bermain dengannya. Sekarang, Anda khawatir itu akan pecah. Jadi, Anda memberinya piring plastik saja. Itu akan menjadi Mock (perilaku yang sama, antarmuka yang sama, implementasi "lebih lembut").
Sekarang, katakan Anda tidak memiliki pengganti plastik, jadi Anda menjelaskan "Jika Anda terus bermain dengan itu, itu akan rusak!". Itu sebuah rintisan , Anda memberikan status yang telah ditentukan sebelumnya.
A Dummy akan menjadi garpu yang bahkan tidak dia gunakan ... dan Spy bisa menjadi sesuatu seperti memberikan penjelasan yang sama yang sudah Anda gunakan yang berfungsi.
sumber
Saya pikir perbedaan paling penting di antara mereka adalah niat mereka.
Biarkan saya mencoba menjelaskannya di MENGAPA rintisan vs MENGAPA tiruan
Misalkan saya sedang menulis kode uji untuk pengontrol waktu publik mac twitter klien saya
Berikut adalah contoh kode uji
Dengan menulis tiruan, Anda menemukan hubungan objek kolaborasi dengan memverifikasi harapan terpenuhi, sementara rintisan hanya mensimulasikan perilaku objek.
Saya sarankan untuk membaca artikel ini jika Anda ingin tahu lebih banyak tentang ejekan: http://jmock.org/oopsla2004.pdf
sumber
Agar sangat jelas dan praktis:
Stub: Kelas atau objek yang mengimplementasikan metode kelas / objek untuk dipalsukan dan selalu mengembalikan apa yang Anda inginkan.
Contoh dalam JavaScript:
Mock: Sama dengan rintisan, tetapi ia menambahkan beberapa logika yang "memverifikasi" ketika suatu metode dipanggil sehingga Anda bisa yakin beberapa implementasi memanggil metode itu.
Seperti yang dikatakan @mLevan bayangkan sebagai contoh bahwa Anda menguji kelas pendaftaran pengguna. Setelah memanggil Simpan, itu harus memanggil SendConfirmationEmail.
Contoh kode yang sangat bodoh:
sumber
Slide ini menjelaskan perbedaan utama yang sangat baik.
* Dari CSE 403 Kuliah 16, University of Washington (slide dibuat oleh "Marty Stepp")
sumber
Saya suka penjelasan yang dikeluarkan oleh Roy Osherove [tautan video] .
sumber
sumber
lihat Uji Ganda:
Rintisan : Rintisan adalah objek yang menyimpan data yang telah ditentukan dan menggunakannya untuk menjawab panggilan selama tes. Seperti : objek yang perlu mengambil beberapa data dari database untuk merespons pemanggilan metode.
Mengolok-olok : Mengejek adalah benda yang mendaftarkan panggilan yang mereka terima. Dalam pernyataan pengujian, kami dapat memverifikasi pada Mocks bahwa semua tindakan yang diharapkan dilakukan. Seperti : fungsi yang memanggil layanan pengiriman e-mail. untuk lebih lanjut periksa ini .
sumber
Sebuah palsu adalah istilah generik yang dapat digunakan untuk menggambarkan baik rintisan atau objek tiruan (tulisan tangan atau sebaliknya), karena mereka berdua terlihat seperti objek nyata.
Apakah sebuah rintisan palsu atau tiruan tergantung pada bagaimana itu digunakan dalam tes saat ini. Jika digunakan untuk memeriksa interaksi (dinyatakan melawan), itu adalah objek tiruan. Kalau tidak, itu sebuah rintisan.
Palsu membuat tes berjalan dengan lancar. Ini berarti bahwa pembaca tes masa depan Anda akan memahami apa yang akan menjadi perilaku objek palsu, tanpa perlu membaca kode sumbernya (tanpa harus bergantung pada sumber daya eksternal).
Apa artinya tes berjalan dengan lancar?
Contohnya dalam kode di bawah ini:
Anda ingin menguji metode mailService.SendEMail () , untuk melakukan itu Anda perlu mensimulasikan Pengecualian dalam metode pengujian Anda, jadi Anda hanya perlu membuat kelas errorService Stub Palsu untuk mensimulasikan hasil itu, maka kode tes Anda akan dapat menguji metode mailService.SendEMail (). Seperti yang Anda lihat, Anda perlu mensimulasikan hasil yang berasal dari kelas ErrorService Ketergantungan Eksternal lainnya.
sumber
Langsung dari makalah Peran Mock, bukan Objects , oleh pengembang jMock:
Jadi, perbedaan utamanya adalah:
Singkatnya, sementara juga mencoba untuk membubarkan kebingungan dari judul artikel Fowler : ejekan adalah bertopik, tetapi mereka tidak hanya bertopik .
sumber
Saya membaca The Art of Unit Testing , dan menemukan definisi berikut:
sumber
Saya menemukan artikel menarik ini oleh UncleBob The Little Mocker . Ini menjelaskan semua terminologi dengan cara yang sangat mudah dimengerti, jadi ini berguna untuk pemula. Artikel Martin Fowlers sulit dibaca terutama untuk pemula seperti saya.
sumber
Stub membantu kita menjalankan tes. Bagaimana? Ini memberikan nilai yang membantu menjalankan tes. Nilai-nilai ini sendiri tidak nyata dan kami menciptakan nilai-nilai ini hanya untuk menjalankan tes. Misalnya kita membuat HashMap untuk memberi kita nilai yang mirip dengan nilai dalam tabel database. Jadi alih-alih berinteraksi langsung dengan basis data, kami berinteraksi dengan Hashmap.
Mock adalah objek palsu yang menjalankan tes. tempat kami menegaskan.
sumber
Lihat di bawah ini contoh tiruan vs bertopik menggunakan C # dan Moq framework. Moq tidak memiliki kata kunci khusus untuk Rintisan tetapi Anda dapat menggunakan objek Mock untuk membuat rintisan juga.
sumber
Sudut pandang pengujian rintisan dan Mock:
Stub adalah implementasi dummy yang dilakukan oleh pengguna dengan cara statis yaitu dalam tulisan rintisan kode implementasi. Jadi tidak bisa menangani definisi layanan dan kondisi dinamis, Biasanya ini dilakukan dalam kerangka JUnit tanpa menggunakan kerangka kerja mocking.
Mock juga merupakan implementasi tiruan tetapi implementasinya dilakukan secara dinamis dengan menggunakan kerangka kerja Mocking seperti Mockito. Jadi kita dapat menangani definisi kondisi dan layanan sebagai cara dinamis yaitu tiruan dapat dibuat secara dinamis dari kode saat runtime. Jadi menggunakan tiruan kita bisa mengimplementasikan Rintisan bertopik secara dinamis.
sumber
Ditambah jawaban yang bermanfaat, Salah satu poin paling kuat dalam menggunakan Mock daripada Subs
Jika kolaborator [yang menjadi sandaran kode utama] tidak berada di bawah kendali kami (mis. Dari perpustakaan pihak ketiga),
Dalam hal ini, rintisan lebih sulit untuk ditulis daripada dihina .
sumber
Saya telah menggunakan contoh python dalam jawaban saya untuk menggambarkan perbedaan.
Stub - Stubbing adalah teknik pengembangan perangkat lunak yang digunakan untuk mengimplementasikan metode kelas di awal siklus pengembangan. Mereka digunakan secara umum sebagai pengganti untuk implementasi dari antarmuka yang dikenal, di mana antarmuka tersebut diselesaikan atau diketahui tetapi implementasinya belum diketahui atau diselesaikan. Anda mulai dengan bertopik, yang berarti bahwa Anda hanya menuliskan definisi fungsi ke bawah dan meninggalkan kode aktual untuk nanti. Keuntungannya adalah Anda tidak akan melupakan metode dan Anda dapat terus memikirkan desain Anda sambil melihatnya dalam kode. Anda juga dapat meminta rintisan mengembalikan respons statis sehingga respons tersebut dapat digunakan oleh bagian lain kode Anda dengan segera. Objek rintisan memberikan respons yang valid, tetapi statis apa pun input yang Anda berikan, Anda akan selalu mendapatkan respons yang sama:
Mengejek objek yang digunakan dalam kasus-kasus uji mengejek mereka memvalidasi bahwa metode tertentu disebut pada objek tersebut. Objek tiruan adalah objek simulasi yang meniru perilaku objek nyata dengan cara yang terkontrol. Anda biasanya membuat objek tiruan untuk menguji perilaku beberapa objek lain. Mock memungkinkan kami mensimulasikan sumber daya yang tidak tersedia atau terlalu sulit untuk pengujian unit.
mymodule.py:
test.py:
Ini adalah contoh yang sangat mendasar yang hanya menjalankan rm dan menegaskan parameter yang dipanggil dengannya. Anda dapat menggunakan tiruan dengan objek tidak hanya berfungsi seperti yang ditunjukkan di sini, dan Anda juga dapat mengembalikan nilai sehingga objek tiruan dapat digunakan untuk menggantikan rintisan untuk pengujian.
Lebih lanjut tentang unittest.mock , note di python 2.x mock tidak termasuk dalam unittest tetapi merupakan modul yang dapat diunduh yang dapat diunduh melalui pip (pip install mock).
Saya juga telah membaca "The Art of Unit Testing" oleh Roy Osherove dan saya pikir akan lebih baik jika buku serupa ditulis menggunakan contoh Python dan Python. Jika ada yang tahu tentang buku seperti itu, silakan berbagi. Bersulang :)
sumber
Rintisan adalah benda palsu yang dibangun untuk tujuan pengujian. Mock adalah sebuah rintisan yang merekam apakah panggilan yang diharapkan terjadi secara efektif.
sumber
Stub adalah fungsi kosong yang digunakan untuk menghindari pengecualian yang tidak ditangani selama pengujian:
Mock adalah fungsi buatan yang digunakan untuk menghindari ketergantungan OS, lingkungan atau perangkat keras selama pengujian:
Dalam hal asersi dan negara:
Referensi
sumber
banyak jawaban yang valid di sana tapi saya pikir layak untuk menyebutkan formulir ini paman bob: https://8thlight.com/blog/uncle-bob/2014/05/14/TheLittleMocker.html
Penjelasan terbaik dengan contoh!
sumber
Mock adalah objek teknis dan fungsional .
Mock itu teknis . Ini memang dibuat oleh perpustakaan mengejek (EasyMock, JMockit dan yang lebih baru-baru ini dikenal dengan Mockito) berkat pembuatan kode byte .
Implementasi tiruan dihasilkan dengan cara di mana kita bisa instrumen itu untuk mengembalikan nilai tertentu ketika suatu metode dipanggil tetapi juga beberapa hal lain seperti memverifikasi bahwa metode tiruan itu dipanggil dengan beberapa parameter tertentu (pemeriksaan ketat) atau apa pun parameternya ( tidak ada pemeriksaan ketat).
Membuat contoh tiruan:
Merekam perilaku:
Memverifikasi permohonan:
Ini jelas bukan cara alami untuk membuat instance / menimpa kelas / perilaku Foo. Itu sebabnya saya merujuk pada aspek teknis.
Tetapi tiruannya juga fungsional karena ini adalah instance dari kelas yang perlu kita isolasi dari SUT. Dan dengan perilaku yang direkam, kita bisa menggunakannya dalam SUT dengan cara yang sama daripada yang kita lakukan dengan rintisan.
Stub hanyalah sebuah objek fungsional : itu adalah instance dari kelas yang perlu kita isolasi dari SUT dan itu saja. Itu berarti bahwa baik kelas rintisan dan semua perlengkapan perilaku yang diperlukan selama tes unit kami harus didefinisikan secara eksplisit.
Sebagai contoh, rintisan
hello()
perlu mensubclassFoo
kelas (atau mengimplementasikan antarmuka yang dimilikinya) dan menimpahello()
:Jika skenario pengujian lain membutuhkan pengembalian nilai lain, kita mungkin perlu menentukan cara umum untuk mengatur pengembalian:
Skenario lain: jika saya memiliki metode efek samping (tidak ada pengembalian) dan saya akan memeriksa bahwa metode itu dipanggil, saya mungkin harus menambahkan boolean atau penghitung di kelas rintisan untuk menghitung berapa kali metode itu dipanggil.
Kesimpulan
Rintisan membutuhkan sering banyak overhead / kode untuk menulis untuk pengujian unit Anda. Mock apa yang mencegah berkat menyediakan fitur perekaman / verifikasi di luar kotak.
Itu sebabnya saat ini, pendekatan rintisan jarang digunakan dalam praktik dengan munculnya perpustakaan tiruan yang sangat baik.
Tentang Artikel Martin Fowler: Saya tidak berpikir untuk menjadi programmer "mockist" ketika saya menggunakan mock dan saya menghindari bertopik.
Tapi saya menggunakan tiruan ketika itu benar-benar diperlukan (dependensi yang mengganggu) dan saya lebih suka tes slicing dan mini-integrasi ketika saya menguji kelas dengan dependensi yang mengejek akan menjadi overhead.
sumber