Bagaimana benda tiruan umumnya disalahgunakan?

15

Saya membaca sebuah artikel baru-baru ini yang mengatakan bahwa benda tiruan sering disalahpahami dan disalahgunakan. Apakah ada anti-pola mengejek yang jelas yang bisa saya perhatikan?

Armand
sumber
Apakah artikel yang Anda baca ini? martinfowler.com/articles/mocksArentStubs.html
keppla
tidak ... tidak dapat mengingat sumber pastinya tetapi akan memposting di sini jika saya melakukannya
Armand
Saya dibawa ke tugas di stackoverflow untuk mengejek API mongodb. Saya diarahkan ke sebuah posting blog yang mengklaim bahwa mengejek kelas mana pun yang Anda sendiri tidak tulis. Saya sebenarnya tidak setuju dengan ini tetapi pendapat itu ada di luar sana.
Kevin

Jawaban:

13

Aku benci melihat kelas beton sederhana diejek. Sebagai contoh, ambil kelas sederhana berikut yang tidak memiliki ketergantungan pada hal lain:

public class Person
{
    private readonly string _firstName;
    private readonly string _surname;

    public Person(string firstName, string surname)
    {
        if (String.IsNullOrEmpty(firstName))
        {
            throw new ArgumentException("Must have first name");
        }

        if (String.IsNullOrEmpty(surname))
        {
            throw new ArgumentException("Must have a surname");
        }

        _firstName = firstName;
        _surname = surname;
    }

    public string Name 
    {
        get
        {
            return _firstName + " " + _surname;
        }
    }
}

Dalam setiap tes yang melibatkan kelas ini, saya lebih suka yang asli dipakai dan digunakan daripada beberapa antarmuka seperti 'IPerson' ditarik keluar, yang mengejek digunakan dan harapan yang ditetapkan pada. Dengan menggunakan yang asli pengujian Anda lebih realistis (Anda memiliki parameter yang memeriksa di tempat dan implementasi nyata dari properti 'Nama'). Untuk kelas sederhana seperti ini Anda tidak membuat tes Anda lebih lambat, kurang deterministik atau berlumpur logika (Anda tidak perlu tahu bahwa Nama dipanggil saat menguji beberapa kelas lain) - yang merupakan alasan biasa untuk mengejek / stubbing.

Sebagai perpanjangan dari ini saya juga melihat orang-orang menulis tes di mana tiruan itu diatur dengan harapan, maka tiruan itu disebut langsung dalam ujian. Tanpa mengherankan tes akan selalu berlalu ... hmmmm ...

FinnNk
sumber
Syukurlah mengejek kerangka kerja yang saya gunakan telah mampu mengejek kelas konkret, jadi menarik antarmuka pada titik-titik yang tidak nyaman bukanlah masalah.
Armand
5
Itu tidak mengubah masalah - hal sederhana semacam ini umumnya tidak boleh diejek bahkan jika Anda menggunakan sesuatu yang melonggarkan kendala teknis tentang apa yang dapat diejek (misalnya kerangka kerja tiruan seperti TypeMock atau bahasa dinamis).
FinnNk
Aturan praktis saya adalah selalu mengejek perilaku, bukan untuk data.
ardave
10

Mungkin terdengar jelas, tetapi: Jangan menggunakan benda tiruan dalam kode produksi! Saya telah melihat lebih dari satu contoh di mana kode produksi bergantung pada karakteristik objek tiruan tertentu ( MockHttpServletRequestdari Springframework misalnya).

perdian
sumber
14
saya harap Anda mengikuti tugas suci Anda dan mengirimkan kode ke DailyWTF?
keppla
1
Dalam pekerjaan saya sebelumnya, kami secara tegas dilarang mengirimkan apa pun dari basis kode kami ke DWTF.
quant_dev
9
@quant_dev: Fakta bahwa mereka memiliki kebijakan seperti itu menyiratkan hal-hal menakutkan tentang pengembang mereka ...
John Fisher
1
Tidak juga. Itu adalah startup yang harus mengembangkan basis kode dengan cepat untuk menjual produk, dan kemudian mulai mengkonsolidasikan dan refactoring untuk melunasi hutang teknis, karena produk jatuh tempo dan pengembangan lebih lanjut terhalang oleh (kurangnya) desain awal. Manajer tahu basis kode lama itu omong kosong, dan menginvestasikan waktu dan sumber daya ke dalam refactoring, tetapi tidak mau mengambil risiko publisitas yang merugikan.
quant_dev
Hanya mengambil jalan pintas tidak benar-benar cukup hanya untukmu setiap hari ...
poolie
9

Menurut pendapat saya itu adalah pemeriksaan doa metode berlebihan pada mock. Saya merasa bahwa ini adalah praktik yang ditegakkan oleh beberapa kerangka kerja mengejek seperti EasyMock, di mana perilaku mock default adalah gagal setiap kali ada doa metode tambahan yang tidak ditentukan secara spesifik sebelumnya. Pemeriksaan metode tiruan ketat semacam ini dapat menyebabkan desain rapuh di mana perubahan terkecil pada kode dapat menyebabkan serangkaian pengujian gagal, meskipun fungsionalitas inti masih sama.

Solusi untuk ini adalah mulai menggunakan bertopik bukannya mengolok-olok. Sebuah artikel yang saya temukan sangat mencerahkan tentang subjek ini ditemukan di Javadoc Mockito: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (lihat "2. Bagaimana dengan beberapa stubbing?" ), menghubungkan ke: http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/ .

Saya menikmati bekerja dengan Mockito sejauh ini karena tidak menegakkan perilaku mengejek yang ketat ini tetapi menggunakan bertopik. Ini juga memberlakukan metode pemeriksaan pada yang spesifik, bukan seluruh objek tiruan; sehingga Anda akhirnya hanya memeriksa metode yang benar-benar penting dalam skenario pengujian Anda.

Ada beberapa buku di sana-sini yang bisa saya rekomendasikan yang menyentuh subjek ini dan mengejek dan umum:

xUnit Pola

Seni Pengujian Unit: Dengan Contoh di .Net

Next Generation Java Testing: TestNG dan Advanced Concepts (buku ini kebanyakan tentang testNG tetapi ada bab yang bagus tentang mengejek)

Fabio Kenji
sumber
+1 untuk poin pada pemeriksaan pemanggilan metode yang berlebihan. Namun, selalu ada sisi lain dari koin di mana doa metode yang tidak terduga menyebabkan kegagalan dalam metode Anda. Untungnya Mockito memiliki Answer.RETURNS_SMART_NULLSpengaturan untuk mengejek yang membantu mendiagnosis ini.
Bringer128
4

Saya telah mengamati beberapa anti-pola dalam pengalaman saya.

  • Kelas-kelas domain diejek / di-stub ketika perubahan status dapat terjadi dan perlu diverifikasi.
  • Tes integrasi berinteraksi dengan campuran mock dan kelas beton yang mengalahkan tujuan tes integrasi.
  • Penggunaan tiruan dalam kode produksi yang tidak sengaja (Ini seharusnya tidak pernah terjadi)

Kalau tidak, pengalaman saya dengan mengolok-olok terutama Mockito sangat mudah. Mereka telah membuat tes yang sangat mudah untuk ditulis dan dipelihara. Pengujian interaksi tampilan / presenter GWT jauh lebih mudah dengan mengejek daripada GWTTestCase.

Vinod R
sumber
2 & 3 adalah masalah yang pasti! Apakah Anda punya contoh sederhana (1)?
Armand
2

Saya menemukan bahwa tes yang memanfaatkan tiruan di beberapa lapisan aplikasi sangat sulit untuk diuraikan dan diubah. Namun saya pikir ini telah dimitigasi dalam beberapa tahun terakhir oleh API kerangka kerja yang ditingkatkan (saya menggunakan JMock di mana nyaman).

5 atau 6 tahun yang lalu API seperti EasyMock sangat kuat tetapi sangat rumit. Seringkali kode pengujian yang memanfaatkannya adalah perintah yang besarnya lebih rumit daripada kode yang diuji. Saat itu saya mencoba untuk mempengaruhi tim saya menggunakannya dengan sangat hemat dan puas dengan tiruan kerajinan tangan sederhana yang hanya implementasi alternatif dari antarmuka khusus untuk pengujian.

Baru-baru ini pendapat saya yang kuat tentang ini menjadi lebih lembut karena API mengejek telah membuat tes yang memanfaatkannya lebih mudah dibaca. Pada dasarnya saya ingin kode saya (termasuk tes) dapat diubah oleh pengembang lain tanpa membuat mereka merasa seperti sedang menyaring lumpur panggilan API yang tidak jelas.

rupjones
sumber