Haruskah saya menghindari metode pribadi jika saya melakukan TDD?

100

Saya baru saja belajar TDD. Ini pemahaman saya bahwa metode pribadi tidak dapat diuji dan tidak perlu khawatir karena API publik akan memberikan informasi yang cukup untuk memverifikasi integritas suatu objek.

Saya sudah mengerti OOP untuk sementara waktu. Ini pemahaman saya bahwa metode pribadi membuat objek lebih dienkapsulasi, sehingga lebih tahan terhadap perubahan dan kesalahan. Dengan demikian, mereka harus digunakan secara default dan hanya metode-metode yang penting bagi klien yang harus dipublikasikan.

Yah, mungkin bagi saya untuk membuat objek yang hanya memiliki metode pribadi dan berinteraksi dengan objek lain dengan mendengarkan acara mereka. Ini akan sangat dirangkum, tetapi sama sekali tidak dapat diuji.

Juga, itu dianggap praktik buruk untuk menambahkan metode demi pengujian.

Apakah ini berarti TDD bertentangan dengan enkapsulasi? Apa saldo yang tepat? Saya cenderung membuat sebagian besar atau semua metode saya publik sekarang ...

anak anjing
sumber
9
Praktik buruk dan kenyataan dalam industri perangkat lunak adalah binatang yang berbeda. Situasi yang ideal lebih sering daripada kenyataan yang terdistorsi dalam dunia bisnis. Lakukan apa yang masuk akal dan patuhi seluruh aplikasi. Saya lebih suka memiliki praktik buruk di tempat daripada rasa bulan tersebar di aplikasi.
Aaron McIver
10
"Metode pribadi tidak bisa diuji"? Bahasa apa? Dalam beberapa bahasa itu merepotkan. Dalam bahasa lain itu sangat sederhana. Juga, apakah Anda mengatakan bahwa prinsip desain enkapsulasi harus selalu diimplementasikan dengan banyak metode pribadi? Tampaknya agak ekstrem. Beberapa bahasa tidak memiliki metode pribadi, namun, tampaknya masih memiliki desain yang dienkapsulasi dengan baik.
S.Lott
"Ini pemahaman saya bahwa metode pribadi membuat objek lebih dikemas, sehingga lebih tahan terhadap perubahan dan kesalahan. Dengan demikian, mereka harus digunakan secara default dan hanya metode yang penting bagi klien yang harus dipublikasikan." Bagi saya ini seperti pandangan yang berlawanan dengan apa yang berusaha dicapai oleh TDD. TDD adalah metodologi pengembangan yang mengarahkan Anda untuk membuat desain yang sederhana, bisa diterapkan, dan terbuka terhadap perubahan. Mencari "dari pribadi" dan "hanya mempublikasikan ..." diputar balik sepenuhnya. Lupa ada yang namanya metode pribadi untuk merangkul TDD. Kemudian, lakukan sesuai kebutuhan; sebagai bagian dari refactoring.
herby
Kemungkinan rangkap dari Metode pribadi pengujian sebagai dilindungi
nyamuk
Jadi, menurut Anda, apakah ini harus ditutup sebagai duplikat dari pertanyaan yang muncul dari jawaban saya untuk pertanyaan ini? * 8 ')
Mark Booth

Jawaban:

50

Lebih suka pengujian ke antarmuka daripada pengujian pada implementasi.

Ini pemahaman saya bahwa metode pribadi tidak dapat diuji

Ini tergantung pada lingkungan pengembangan Anda, lihat di bawah.

[metode pribadi] tidak perlu khawatir karena API publik akan memberikan informasi yang cukup untuk memverifikasi integritas objek.

Benar, TDD berfokus pada pengujian antarmuka.

Metode pribadi adalah detail implementasi yang dapat berubah selama siklus faktor-ulang. Seharusnya dimungkinkan untuk faktor ulang tanpa mengubah antarmuka atau perilaku kotak hitam . Bahkan, itu adalah bagian dari manfaat TDD, kemudahan yang Anda gunakan untuk menghasilkan kepercayaan bahwa perubahan internal ke kelas tidak akan memengaruhi pengguna kelas itu.

Yah, mungkin bagi saya untuk membuat objek yang hanya memiliki metode pribadi dan berinteraksi dengan objek lain dengan mendengarkan acara mereka. Ini akan sangat dirangkum, tetapi sama sekali tidak dapat diuji.

Bahkan jika kelas tidak memiliki metode umum, itu event yang itu antarmuka publik , dan terhadap yang antarmuka publik bahwa Anda dapat menguji.

Karena peristiwa adalah antarmuka maka itu adalah peristiwa yang Anda perlu hasilkan untuk menguji objek itu.

Lihatlah menggunakan benda tiruan sebagai lem untuk sistem pengujian Anda. Seharusnya dimungkinkan untuk membuat objek tiruan sederhana yang menghasilkan suatu peristiwa dan mengambil perubahan status yang dihasilkan (dimungkinkan oleh objek tiruan penerima lain).

Juga, itu dianggap praktik buruk untuk menambahkan metode demi pengujian.

Tentu saja, Anda harus sangat berhati - hati dalam mengekspos keadaan internal.

Apakah ini berarti TDD bertentangan dengan enkapsulasi? Apa saldo yang tepat?

Benar-benar tidak.

TDD seharusnya tidak mengubah implementasi kelas Anda selain untuk menyederhanakannya (dengan menerapkan YAGNI dari poin sebelumnya).

Praktik terbaik dengan TDD identik dengan praktik terbaik tanpa TDD, Anda baru tahu mengapa lebih cepat, karena Anda menggunakan antarmuka saat Anda mengembangkannya.

Saya cenderung membuat sebagian besar atau semua metode saya publik sekarang ...

Ini lebih baik membuang bayi keluar dengan air mandi.

Anda tidak perlu membuat semua metode terbuka agar Anda dapat mengembangkannya dengan cara TDD. Lihat catatan saya di bawah ini untuk melihat apakah metode pribadi Anda benar-benar tidak dapat diuji.

Pandangan yang lebih rinci pada pengujian metode pribadi

Jika Anda benar-benar harus menguji beberapa perilaku pribadi kelas, tergantung pada bahasa / lingkungannya, Anda mungkin memiliki tiga opsi:

  1. Letakkan tes di kelas yang ingin Anda uji.
  2. Letakkan tes di file kelas / sumber lain & paparkan metode pribadi yang ingin Anda uji sebagai metode publik.
  3. Gunakan lingkungan pengujian yang memungkinkan Anda untuk menjaga kode pengujian dan produksi terpisah, namun masih memungkinkan akses kode pengujian ke metode pribadi dari kode produksi.

Jelas opsi ke-3 sejauh ini adalah yang terbaik.

1) Letakkan tes di kelas yang ingin Anda uji (tidak ideal)

Menyimpan kasus uji dalam file kelas / sumber yang sama dengan kode produksi yang sedang diuji adalah pilihan paling sederhana. Tetapi tanpa banyak arahan pra-prosesor atau anotasi Anda akan berakhir dengan kode pengujian Anda menggembungkan kode produksi Anda tidak perlu, dan tergantung pada bagaimana Anda telah menyusun kode Anda, Anda mungkin berakhir secara tidak sengaja mengekspos implementasi internal kepada pengguna kode itu.

2) Ekspos metode pribadi yang ingin Anda uji sebagai metode publik (benar-benar bukan ide yang baik)

Seperti yang disarankan ini adalah praktik yang sangat buruk, menghancurkan enkapsulasi dan akan memaparkan implementasi internal kepada pengguna kode.

3) Gunakan lingkungan pengujian yang lebih baik (opsi terbaik, jika tersedia)

Di dunia Eclipse, 3. dapat dicapai dengan menggunakan fragmen . Di dunia C #, kita mungkin menggunakan kelas parsial . Bahasa / lingkungan lain sering memiliki fungsi yang serupa, Anda hanya perlu menemukannya.

Dengan asumsi 1. atau 2. adalah satu-satunya pilihan yang kemungkinan akan menghasilkan perangkat lunak produksi yang penuh dengan kode uji atau antarmuka kelas yang buruk yang mencuci linen kotor mereka di depan umum. * 8 ')

  • Secara keseluruhan - jauh lebih baik untuk tidak menguji terhadap implementasi swasta sekalipun.
Mark Booth
sumber
5
Saya tidak yakin saya akan setuju dengan salah satu dari tiga opsi yang Anda sarankan. Preferensi saya adalah hanya menguji antarmuka publik seperti yang Anda katakan sebelumnya, tetapi memastikan bahwa dengan melakukan itu, metode pribadi dilakukan. Bagian dari keuntungan melakukan hal itu adalah menemukan kode mati, yang tidak mungkin terjadi jika Anda memaksakan kode pengujian Anda untuk menghentikan penggunaan bahasa yang normal.
Magus
Metode Anda harus melakukan satu hal, dan tes tidak boleh mempertimbangkan penerapannya dengan cara apa pun. Metode pribadi adalah detail implementasi. Jika hanya menguji metode publik berarti pengujian Anda adalah tes integrasi, Anda memiliki masalah desain.
Magus
Bagaimana dengan menjadikan metode ini standar / terlindungi dan membuat tes dalam proyek uji dengan paket yang sama?
RichardCypher
@ RichardCypher Itu secara efektif sama dengan 2) karena Anda mengubah spesifikasi metode Anda idealnya untuk mengakomodasi kekurangan di lingkungan pengujian Anda, jadi jelas masih praktik yang buruk.
Mark Booth
75

Tentu saja Anda dapat memiliki metode pribadi, dan tentu saja Anda dapat mengujinya.

Entah ada beberapa cara untuk mendapatkan metode swasta untuk menjalankan, dalam hal ini Anda dapat menguji seperti itu, atau ada tidak ada cara untuk mendapatkan swasta untuk menjalankan, dalam hal: mengapa sih yang Anda mencoba untuk menguji itu, hanya hapus saja!

Dalam contoh Anda:

Yah, mungkin bagi saya untuk membuat objek yang hanya memiliki metode pribadi dan berinteraksi dengan objek lain dengan mendengarkan acara mereka. Ini akan sangat dirangkum, tetapi sama sekali tidak dapat diuji.

Mengapa itu tidak dapat diuji? Jika metode ini digunakan sebagai reaksi terhadap suatu peristiwa, mintalah tes untuk memberi makan objek peristiwa yang sesuai.

Ini bukan tentang tidak memiliki metode pribadi, ini tentang tidak melanggar enkapsulasi. Anda dapat memiliki metode pribadi tetapi Anda harus mengujinya melalui API publik. Jika API publik didasarkan pada acara, maka gunakan acara.

Untuk kasus metode pembantu pribadi yang lebih umum, mereka dapat diuji melalui metode publik yang memanggil mereka. Khususnya, karena Anda hanya diperbolehkan menulis kode untuk lulus ujian yang gagal dan tes Anda menguji API publik, semua kode baru yang Anda tulis biasanya akan menjadi publik. Metode pribadi hanya muncul sebagai hasil dari Refactoring Metode Ekstrak , ketika mereka ditarik dari metode publik yang sudah ada. Tetapi dalam kasus itu, tes asli yang menguji metode publik juga masih mencakup metode pribadi, karena metode publik memanggil metode pribadi.

Jadi, biasanya metode pribadi hanya muncul ketika mereka diekstraksi dari metode publik yang sudah diuji dan dengan demikian sudah diuji juga.

Jörg W Mittag
sumber
3
Pengujian melalui metode publik berfungsi dengan baik 99% dari waktu. Tantangannya adalah 1% dari waktu ketika metode publik tunggal Anda memiliki beberapa ratus atau ribuan baris kode kompleks di belakangnya dan semua negara perantara adalah spesifik implementasi. Setelah itu menjadi cukup kompleks mencoba untuk memukul semua kasus tepi dari metode publik menjadi menyakitkan di terbaik. Sebagai alternatif, menguji kasus tepi dengan memecahkan enkapsulasi dan mengekspos lebih banyak metode sebagai pribadi, atau dengan menggunakan kludge untuk melakukan tes panggilan metode pribadi secara langsung menghasilkan kasus uji rapuh selain menjadi jelek.
Dan Neely
24
Metode pribadi yang besar dan kompleks adalah bau kode. Suatu implementasi yang sangat kompleks sehingga tidak dapat dengan mudah didekomposisi menjadi bagian-bagian komponen (dengan antarmuka publik) adalah masalah dalam pengujian yang mengungkapkan potensi desain dan masalah arsitektur. 1% dari kasus-kasus di mana kode pribadi sangat besar biasanya akan mendapat manfaat dari pengerjaan ulang untuk membusuk dan mengekspos.
S.Lott
13
@Dan Neely kode seperti itu sangat tidak dapat diuji terlepas - dan bagian dari tes unit menulis menunjukkan ini. Hilangkan status, putus kelas, terapkan semua refactoring khas dan kemudian tulis unit test. Juga dengan TDD, bagaimana Anda bisa sampai ke titik itu? Ini adalah salah satu kelebihan TDD, penulisan kode yang dapat diuji menjadi otomatis.
Bill K
Setidaknya internalmetode atau metode publik di internalkelas harus diuji secara langsung cukup sering. Untungnya .net mendukung InternalsVisibleToAttribute, tetapi tanpa itu, pengujian metode tersebut akan menjadi PITA.
CodesInChaos
25

Ketika Anda membuat kelas baru dalam kode Anda, Anda melakukannya untuk menjawab beberapa persyaratan. Persyaratan mengatakan apa yang harus dilakukan kode, bukan bagaimana . Ini membuatnya mudah untuk memahami mengapa sebagian besar pengujian terjadi pada tingkat metode publik.

Melalui pengujian, kami memverifikasi bahwa kode melakukan apa yang diharapkan , melemparkan pengecualian yang sesuai saat diharapkan, dll. Kami tidak terlalu peduli bagaimana kode tersebut diterapkan oleh pengembang. Meskipun kami tidak peduli tentang implementasi, yaitu bagaimana kode melakukan apa yang dilakukannya, masuk akal untuk menghindari pengujian metode pribadi.

Sedangkan untuk kelas pengujian yang tidak memiliki metode publik dan berinteraksi dengan dunia luar hanya melalui acara, Anda dapat menguji ini juga dengan mengirimkan, melalui tes, acara dan mendengarkan respons. Sebagai contoh jika suatu kelas harus menyimpan file log setiap kali menerima suatu peristiwa, uji unit akan mengirim peristiwa dan memverifikasi bahwa file log ditulis.

Terakhir namun tidak kalah pentingnya, dalam beberapa kasus sangat sah untuk menguji metode pribadi. Itu sebabnya misalnya dalam. NET, Anda dapat menguji tidak hanya publik, tetapi juga kelas privat, bahkan jika solusinya tidak semudah untuk metode publik.

Arseni Mourzenko
sumber
4
+1 Salah satu fitur penting dari TDD adalah ia memaksa Anda untuk menguji bahwa PERSYARATAN terpenuhi, daripada menguji bahwa METODE melakukan apa yang menurut mereka Anda lakukan. Jadi pertanyaan "Bisakah saya menguji metode pribadi" agak bertentangan dengan semangat TDD - pertanyaannya mungkin adalah "Bisakah saya menguji persyaratan yang implementasinya mencakup metode pribadi". Dan jawaban untuk pertanyaan ini jelas ya.
Dawood ibn Kareem
6

Ini pemahaman saya bahwa metode pribadi tidak dapat diuji

Saya tidak setuju dengan pernyataan itu, atau saya akan mengatakan Anda tidak menguji metode pribadi secara langsung . Metode publik dapat memanggil metode pribadi yang berbeda. Mungkin penulis ingin memiliki metode "kecil" dan mengekstraksi beberapa kode menjadi metode pribadi bernama cerdik.

Terlepas dari bagaimana metode publik ditulis, kode pengujian Anda harus mencakup semua jalur. Jika Anda menemukan setelah pengujian Anda bahwa salah satu pernyataan cabang (jika / beralih) dalam satu metode pribadi tidak pernah tercakup dalam pengujian Anda, maka Anda memiliki masalah. Entah Anda melewatkan sebuah kasus dan implementasinya benar ATAU implementasinya salah, dan cabang itu seharusnya tidak pernah ada.

Itulah sebabnya saya sering menggunakan Cobertura dan NCover, untuk memastikan bahwa pengujian metode publik saya juga mencakup metode pribadi. Jangan ragu untuk menulis objek OO yang baik dengan metode pribadi dan jangan biarkan TDD / Pengujian menghalangi Anda dalam hal tersebut.

Jalayn
sumber
5

Contoh Anda masih dapat diuji dengan sempurna selama Anda menggunakan Ketergantungan Injeksi untuk memberikan contoh yang berinteraksi dengan CUT Anda. Kemudian Anda dapat menggunakan tiruan, menghasilkan acara yang menarik, dan kemudian mengamati apakah CUT mengambil tindakan yang benar pada dependensinya.

Di sisi lain, jika Anda memiliki bahasa dengan dukungan acara yang baik, Anda mungkin mengambil jalur yang sedikit berbeda. Saya tidak suka ketika objek berlangganan ke acara itu sendiri, sebagai gantinya memiliki pabrik yang membuat objek menghubungkan peristiwa dengan metode publik objek. Lebih mudah untuk diuji, dan membuatnya terlihat secara eksternal seperti apa peristiwa yang CUT harus diuji.

Chris Pitman
sumber
Itu ide yang bagus - "... mintalah pabrik yang membuat objek menghubungkan peristiwa dengan metode publik objek. Lebih mudah untuk menguji, dan membuatnya terlihat secara eksternal seperti apa peristiwa yang CUT perlu diuji. "
anak anjing
5

Anda tidak perlu meninggalkan menggunakan metode pribadi. Sangat masuk akal untuk menggunakannya, tetapi dari perspektif pengujian, lebih sulit untuk menguji secara langsung tanpa melanggar enkapsulasi atau menambahkan kode khusus tes ke kelas Anda. Caranya adalah dengan meminimalkan hal-hal yang Anda tahu akan membuat usus Anda menggeliat karena Anda merasa seperti Anda telah mengotori kode Anda.

Ini adalah hal-hal yang saya ingat untuk mencoba dan mencapai keseimbangan yang bisa diterapkan.

  1. Minimalkan jumlah metode dan properti pribadi yang Anda gunakan. Sebagian besar hal yang perlu dilakukan kelas Anda cenderung perlu diekspos secara terbuka, jadi pikirkan apakah Anda benar-benar perlu menjadikan metode pintar itu pribadi.
  2. Minimalkan jumlah kode dalam metode pribadi Anda - Anda benar-benar harus melakukan ini - dan menguji secara tidak langsung di mana Anda dapat melalui perilaku metode lain. Anda tidak pernah berharap untuk mendapatkan cakupan pengujian 100%, dan mungkin Anda perlu memeriksa beberapa nilai melalui debugger. Menggunakan metode pribadi untuk melempar Pengecualian dapat dengan mudah diuji secara tidak langsung. Properti pribadi mungkin perlu diuji secara manual, atau melalui metode lain.
  3. Jika pemeriksaan tidak langsung atau manual tidak cocok dengan Anda, tambahkan acara yang dilindungi dan akses melalui Antarmuka untuk mengekspos beberapa hal pribadi. Ini secara efektif "membengkokkan" aturan enkapsulasi, tetapi menghindari keharusan untuk benar-benar mengirimkan kode yang menjalankan pengujian Anda. Kekurangannya adalah ini dapat menghasilkan sedikit kode internal tambahan untuk memastikan bahwa acara akan dipecat ketika diperlukan.
  4. Jika Anda merasa bahwa metode publik tidak cukup "aman", lihat apakah ada cara Anda dapat menerapkan semacam proses validasi dalam metode Anda untuk membatasi penggunaannya. Kemungkinannya adalah ketika Anda memikirkan hal ini baik memikirkan cara yang lebih baik untuk mengimplementasikan metode Anda, atau Anda akan melihat kelas lain mulai terbentuk.
  5. Jika Anda memiliki banyak metode pribadi yang melakukan "hal-hal" untuk metode publik Anda, mungkin ada kelas baru yang menunggu untuk diekstraksi. Anda dapat menguji ini secara langsung sebagai kelas yang terpisah, tetapi menerapkannya sebagai komposit secara pribadi di dalam kelas yang menggunakannya.

Pikirkan secara lateral. Pertahankan kelas Anda kecil dan metode Anda lebih kecil, dan gunakan banyak komposisi. Kedengarannya seperti lebih banyak pekerjaan, tetapi pada akhirnya Anda akan berakhir dengan lebih banyak item yang dapat diuji secara individual, tes Anda akan lebih sederhana, Anda akan memiliki lebih banyak pilihan untuk menggunakan tiruan sederhana di tempat benda nyata, besar dan kompleks, mudah-mudahan well- kode faktor dan longgar digabungkan, dan yang lebih penting Anda akan memberi diri Anda lebih banyak pilihan. Menjaga hal-hal kecil cenderung menghemat waktu Anda pada akhirnya, karena Anda mengurangi jumlah hal yang perlu Anda periksa secara individual di setiap kelas, dan Anda cenderung mengurangi spaghetti kode yang kadang-kadang dapat terjadi ketika kelas menjadi besar dan memiliki banyak perilaku kode interdependen secara internal.

S.Robins
sumber
4

Yah, mungkin bagi saya untuk membuat objek yang hanya memiliki metode pribadi dan berinteraksi dengan objek lain dengan mendengarkan acara mereka. Ini akan sangat dirangkum, tetapi sama sekali tidak dapat diuji.

Bagaimana reaksi objek ini terhadap peristiwa itu? Agaknya, itu harus memanggil metode pada objek lain. Anda dapat mengujinya dengan memeriksa apakah metode-metode itu dipanggil. Apakah itu memanggil objek tiruan dan kemudian Anda dapat dengan mudah menyatakan bahwa ia melakukan apa yang Anda harapkan.

Masalahnya adalah kita hanya ingin menguji interaksi objek dengan objek lain. Kami tidak peduli apa yang terjadi di dalam suatu objek. Jadi tidak, Anda seharusnya tidak memiliki metode publik lebih dari sebelumnya.

Winston Ewert
sumber
4

Saya telah berjuang dengan masalah yang sama juga. Sungguh, cara untuk menyiasatinya adalah ini: Bagaimana Anda mengharapkan sisa program Anda berinteraksi dengan kelas itu? Tes kelas Anda sesuai. Ini akan memaksa Anda untuk mendesain kelas Anda berdasarkan bagaimana program lainnya berinteraksi dengannya dan akan, pada kenyataannya, mendorong enkapsulasi dan desain yang baik dari kelas Anda.

Kesempatan
sumber
3

Alih-alih penggunaan pribadi pengubah standar. Kemudian Anda dapat menguji metode-metode tersebut secara individual, tidak hanya digabungkan dengan metode publik. Ini mengharuskan tes Anda memiliki struktur paket yang sama dengan kode utama Anda.

siamii
sumber
... dengan asumsi ini adalah Java.
Dawood ibn Kareem
atau internaldalam .net.
CodesInChaos
2

Beberapa metode pribadi biasanya tidak menjadi masalah. Anda cukup mengujinya melalui API publik seolah-olah kode itu dimasukkan ke dalam metode publik Anda. Kelebihan metode pribadi mungkin merupakan tanda kohesi yang buruk. Kelas Anda harus memiliki satu tanggung jawab yang kohesif, dan seringkali orang membuat metode pribadi untuk memberikan kesan keterpaduan di mana tidak ada yang benar-benar ada.

Misalnya, Anda mungkin memiliki pengendali aktivitas yang membuat banyak panggilan basis data sebagai respons terhadap peristiwa tersebut. Karena jelas merupakan praktik yang buruk untuk membuat event handler untuk membuat panggilan basis data, godaannya adalah membuat semua panggilan yang terkait dengan basis data metode pribadi, ketika mereka harus benar-benar ditarik keluar ke kelas yang terpisah.

Karl Bielefeldt
sumber
2

Apakah ini berarti TDD bertentangan dengan enkapsulasi? Apa saldo yang tepat? Saya cenderung membuat sebagian besar atau semua metode saya publik sekarang.

TDD tidak berselisih dengan enkapsulasi. Ambil contoh paling sederhana dari metode atau properti pengambil, tergantung pada bahasa pilihan Anda. Katakanlah saya memiliki objek Pelanggan dan saya ingin memiliki bidang ID. Tes pertama yang akan saya tulis adalah tes yang mengatakan sesuatu seperti "customer_id_initializes_to_zero". Saya mendefinisikan pengambil untuk melempar pengecualian yang tidak diimplementasikan dan menonton tes gagal. Kemudian, hal paling sederhana yang bisa saya lakukan untuk membuat tes lulus adalah mendapatkan pengambil kembali nol.

Dari sana, saya pergi ke tes lain, mungkin yang melibatkan ID pelanggan menjadi bidang fungsional aktual. Pada titik tertentu, saya mungkin harus membuat bidang pribadi yang digunakan kelas pelanggan untuk melacak apa yang harus dikembalikan oleh pengambil. Bagaimana tepatnya cara saya melacak ini? Apakah ini backing int sederhana? Apakah saya melacak string dan kemudian mengubahnya menjadi int? Apakah saya melacak 20 int dan rata-rata? Dunia luar tidak peduli - dan tes TDD Anda tidak peduli. Itu adalah detail yang dirangkum .

Saya pikir ini tidak selalu segera jelas ketika memulai TDD - Anda tidak menguji metode apa yang dilakukan secara internal - Anda menguji kurang perhatian granular kelas. Jadi, Anda tidak mencari untuk menguji metode yang DoSomethingToFoo()instantiates Bar, memanggil metode di atasnya, menambahkan dua ke salah satu propertinya, dll. Anda sedang menguji bahwa setelah Anda mengubah keadaan objek Anda, beberapa accessor negara telah berubah (atau tidak). Itulah pola umum dari tes Anda: "ketika saya melakukan X ke kelas saya yang diuji, saya kemudian bisa mengamati Y". Bagaimana hal itu sampai ke Y bukan urusan tes, dan ini adalah apa yang dienkapsulasi dan inilah mengapa TDD tidak bertentangan dengan enkapsulasi.

Erik Dietrich
sumber
2

Hindari pemakaian? Tidak.
Hindari mulai dengan ? Iya.

Saya perhatikan Anda tidak bertanya apakah boleh memiliki kelas abstrak dengan TDD; jika Anda memahami bagaimana kelas abstrak muncul selama TDD, prinsip yang sama juga berlaku untuk metode pribadi.

Anda tidak dapat langsung menguji metode dalam kelas abstrak sama seperti Anda tidak bisa langsung menguji metode pribadi, tapi itu sebabnya Anda tidak memulai dengan kelas abstrak dan metode pribadi; Anda mulai dengan kelas-kelas konkret dan API publik, dan kemudian Anda refactor fungsi umum saat Anda pergi.


sumber