Apa cara terbaik untuk menguji unit metode yang tidak mengembalikan apa pun? Khususnya dalam c #.
Apa yang saya benar-benar coba untuk menguji adalah metode yang mengambil file log dan mem-parsing untuk string tertentu. String kemudian dimasukkan ke dalam basis data. Tidak ada yang belum pernah dilakukan sebelumnya tetapi menjadi SANGAT baru untuk TDD saya bertanya-tanya apakah mungkin untuk menguji ini atau itu sesuatu yang tidak benar-benar diuji.
c#
unit-testing
jdiaz
sumber
sumber
Jawaban:
Jika suatu metode tidak mengembalikan apa pun, itu salah satu dari yang berikut ini
Metode imperatif - Anda dapat memverifikasi apakah tugas itu benar-benar dilakukan. Verifikasi apakah perubahan status benar-benar terjadi. misalnya
dapat diuji dengan memverifikasi apakah saldo posting pesan ini memang kurang dari nilai awal oleh dAmount
Metode informasi - jarang sebagai anggota antarmuka publik objek ... karenanya tidak biasanya diuji unit. Namun jika Anda harus, Anda dapat memverifikasi apakah penanganan yang dilakukan pada pemberitahuan terjadi. misalnya
dapat diuji dengan memverifikasi apakah email sedang dikirim
Posting detail lebih lanjut tentang metode Anda yang sebenarnya dan orang-orang akan dapat menjawab dengan lebih baik.
Pembaruan : Metode Anda melakukan 2 hal. Saya sebenarnya akan membaginya menjadi dua metode yang sekarang dapat diuji secara independen.
String [] dapat dengan mudah diverifikasi dengan memberikan metode pertama dengan file dummy dan string yang diharapkan. Yang kedua agak rumit .. Anda bisa menggunakan Mock (google atau mencari stackoverflow pada mocking frameworks) untuk meniru DB atau menekan DB yang sebenarnya dan memverifikasi apakah string dimasukkan di lokasi yang tepat. Periksa utas ini untuk beberapa buku bagus ... Saya akan merekomendasikan kembali Pengujian Unit Pragmatis jika Anda berada dalam krisis.
Dalam kode itu akan digunakan seperti
sumber
Uji efek sampingnya. Ini termasuk:
Tentu saja, ada batasan seberapa banyak Anda dapat menguji. Anda biasanya tidak dapat menguji dengan setiap input yang mungkin, misalnya. Uji secara pragmatis - cukup untuk memberi Anda keyakinan bahwa kode Anda dirancang dengan tepat dan diimplementasikan dengan benar, dan cukup untuk bertindak sebagai dokumentasi tambahan untuk apa yang mungkin diharapkan oleh penelepon.
sumber
Seperti biasa: uji apa metode yang seharusnya dilakukan!
Haruskah itu mengubah keadaan global (ya, bau kode!) Di suatu tempat?
Haruskah itu memanggil antarmuka?
Haruskah ia melempar pengecualian ketika dipanggil dengan parameter yang salah?
Haruskah tidak ada pengecualian saat dipanggil dengan parameter yang tepat?
Haruskah itu ...?
sumber
Jenis pengembalian tidak valid / Subrutin adalah berita lama. Saya belum membuat tipe Void return (Kecuali saya menjadi sangat malas) dalam waktu 8 tahun (Dari saat jawaban ini, jadi hanya sedikit sebelum pertanyaan ini diajukan).
Alih-alih metode seperti:
Buat metode yang mengikuti paradigma int.TryParse () Microsoft:
Mungkin tidak ada informasi metode Anda perlu kembali untuk digunakan dalam jangka panjang, tetapi mengembalikan keadaan metode setelah melakukan tugasnya adalah penggunaan yang sangat besar bagi penelepon.
Juga, bool bukan satu-satunya tipe negara. Ada beberapa kali Subroutine yang dibuat sebelumnya benar-benar dapat mengembalikan tiga keadaan yang berbeda (Baik, Normal, Buruk, dll.). Dalam kasus itu, Anda hanya akan menggunakan
Namun, sementara Try-Paradigm agak menjawab pertanyaan ini tentang cara menguji void return, ada pertimbangan lain juga. Misalnya, selama / setelah siklus "TDD", Anda akan "Refactoring" dan perhatikan Anda melakukan dua hal dengan metode Anda ... sehingga melanggar "Prinsip Tanggung Jawab Tunggal." Jadi itu harus diurus dulu. Kedua, Anda mungkin telah mengidentifikasi ketergantungan ... Anda menyentuh Data "Persisten".
Jika Anda melakukan hal-hal akses data dalam metode-dalam-pertanyaan, Anda perlu merevisi ke dalam arsitektur n-tier'd atau n-layer'd. Tetapi kita dapat mengasumsikan bahwa ketika Anda mengatakan "string kemudian dimasukkan ke dalam database", Anda sebenarnya berarti Anda memanggil lapisan logika bisnis atau sesuatu. Ya, kami akan menganggap itu.
Ketika objek Anda dipakai, Anda sekarang mengerti bahwa objek Anda memiliki dependensi. Inilah saatnya Anda perlu memutuskan apakah akan melakukan Injeksi Ketergantungan pada Objek, atau pada Metode. Itu berarti Konstruktor Anda atau metode-dalam-pertanyaan memerlukan Parameter baru:
Sekarang Anda dapat menerima antarmuka objek tingkat bisnis / data Anda, Anda dapat mengejeknya selama Tes Unit dan tidak memiliki ketergantungan atau takut terhadap pengujian integrasi "Terkadang".
Jadi dalam kode langsung Anda, Anda memasukkan
IBusinessDataEtc
objek NYATA . Tetapi dalam Unit Testing Anda, Anda meneruskanIBusinessDataEtc
objek MOCK . Di Mock itu, Anda bisa menyertakan Properti Non-Antarmuka sepertiint XMethodWasCalledCount
atau sesuatu yang statusnya diperbarui ketika metode antarmuka dipanggil.Jadi Tes Unit Anda akan melalui Metode Anda -Dalam-Pertanyaan, melakukan logika apa pun yang mereka miliki, dan memanggil satu atau dua, atau serangkaian metode yang dipilih di
IBusinessDataEtc
objek Anda . Ketika Anda melakukan Pernyataan Anda di akhir Tes Unit Anda, Anda memiliki beberapa hal untuk diuji sekarang.IBusinessDataEtc
objek Mock Anda .Untuk informasi lebih lanjut tentang ide-ide Ketergantungan Injeksi pada tingkat Konstruksi ... karena mereka berkaitan dengan Unit Testing ... lihat pola desain Builder. Ini menambahkan satu lagi antarmuka dan kelas untuk setiap antarmuka / kelas saat ini yang Anda miliki, tetapi mereka sangat kecil dan memberikan peningkatan fungsionalitas BESAR untuk Unit-Testing yang lebih baik.
sumber
public void sendEmailToCustomer() throws UndeliveredMailException
?void
metode, terutama dalam bahasa Berorientasi Objek, itu telah menjadi satu-satunya pilihan nyata. Alternatif tertua oleh Microsoft adalah Try-Paradigm yang saya diskusikan, dan paradigma gaya fungsional seperti Monads / Maybes. Dengan demikian, Perintah (Dalam CQS) masih dapat mengembalikan informasi status yang berharga alih-alih mengandalkan melempar, yang mirip denganGOTO
(Yang kita tahu buruk). melempar (dan goto) lambat, sulit untuk debug, dan bukan praktik yang baik.Coba ini:
sumber
ExpectedAttribute
dirancang untuk membuat tes ini lebih jelas.Anda bahkan dapat mencobanya dengan cara ini:
sumber
itu akan memiliki beberapa efek pada objek .... permintaan untuk hasil efek. Jika tidak memiliki efek yang terlihat, pengujian unit tidak layak!
sumber
Mungkin metode ini melakukan sesuatu, dan tidak hanya kembali?
Dengan asumsi inilah masalahnya, maka:
Jika Anda memberi tahu kami apa metode ini, saya bisa lebih spesifik.
sumber
Gunakan Rhino Mocks untuk mengatur panggilan, tindakan, dan pengecualian apa yang mungkin diharapkan. Dengan asumsi Anda dapat mengejek atau mematikan bagian dari metode Anda. Sulit diketahui tanpa mengetahui beberapa spesifik di sini tentang metode, atau bahkan konteks.
sumber
Tergantung pada apa yang dilakukannya. Jika memiliki parameter, masukkan tiruan yang bisa Anda tanyakan nanti jika parameter tersebut dipanggil dengan set parameter yang tepat.
sumber
Apa pun contoh yang Anda gunakan untuk memanggil metode void, Anda bisa menggunakan,
Verfiy
Sebagai contoh:
Dalam kasus saya ini
_Log
adalah contoh danLogMessage
metode yang akan diuji:Apakah
Verify
lemparan pengecualian karena kegagalan metode tes akan Gagal?sumber