Apakah mengikuti TDD pasti mengarah ke DI?

14

Saya belajar melakukan Test Driven Development (TDD), Dependency Injection (DI) dan Inversion of Control (IoC) pada saat bersamaan. Ketika saya menulis kode menggunakan TDD saya selalu berakhir menggunakan DI di konstruktor kelas saya. Saya bertanya-tanya apakah ini karena bagaimana saya belajar melakukan TDD, atau apakah ini adalah efek samping alami dari TDD.

Jadi pertanyaan saya adalah ini: Apakah mengikuti kepala sekolah TDD dan tes unit penulisan yang tidak bergantung pada layanan eksternal pasti mengarah ke DI?

Gilles
sumber
8
Saya membaca The Art of Unit Testing dan dan sepertinya itu memang mengarah ke Dependency Injection (DI).
programmer
2
Jadi bahasa apa ini? DI / etc diperlukan di Jawa, tapi itu karena keterbatasan bahasa - bahasa seperti Python tidak membutuhkannya karena mereka dapat menambal dependensi dalam pengujian.
Izkata
@Izkata: Saya setuju bahwa DI adalah solusi untuk batasan bahasa; tetapi monkeypatching tidak selalu hal yang sama dalam bahasa yang kurang kaku. Di antara cara-cara lain saya lebih suka fungsi kelas satu, yang memungkinkan Anda untuk melakukan secara alami apa yang didekati oleh DI dengan disiplin.
Javier

Jawaban:

19

Apakah mengikuti TDD dan menulis unit test yang tidak bergantung pada database atau layanan eksternal pasti mengarah ke DI?

Untuk definisi DI yang luas, ya. Kelas-kelas tidak ada dalam suatu vaccuum, jadi mereka perlu mengisi dependensinya entah bagaimana. Terkadang hanya memberikan nilai tidak apa-apa. Terkadang Anda perlu memberikan tiruan di konstruktor. Terkadang melalui wadah IOC. Terkadang melalui accessor tes pribadi. Itu semua menyuntikkan beberapa hal uji ke dalam kelas sehingga dapat bekerja secara terpisah.

Telastyn
sumber
9

Bagi orang-orang yang sudah tahu tentang DI, tetapi belum pernah melihat intinya, saya pikir unit testing hampir selalu mengarah pada penggunaan DI.

Jika Anda tidak tahu tentang DI dan mencoba menulis unit test, beberapa orang secara alami akan menemukan kembali DI, beberapa akan merasa frustrasi dan akhirnya menemukan DI melalui penelitian, tetapi Anda akan terkejut betapa sering hal itu tidak akan terjadi pada seseorang. bahwa mungkin ada cara yang lebih baik untuk merancang perangkat lunak mereka agar pengujian unit lebih mudah. Orang-orang itu menghapus pengujian unit sebagai sesuatu yang sulit dan menyerah.

Karl Bielefeldt
sumber
8

Pengujian unit akan mengarah ke DI (karena memaksa Anda untuk membuat unit yang digabungkan secara longgar). TDD belum tentu, karena TDD juga dapat digunakan untuk membuat tes lapis demi lapis, alih-alih tes unit "kata demi kata". Lihat artikel ini

http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx

untuk penjelasan perbedaan.

Doc Brown
sumber
1
+1 untuk "TDD bukan UT". Juga untuk mengetahui bahwa uncoupling yang ekstrem adalah hasil umum dari UT, bukan (tentu) dari TDD.
Javier
3

Ya dan tidak: TDD mengarah ke penulisan kode yang terstruktur dengan baik, yang dengan sendirinya mengarah ke DI.

Maksud saya TDD umumnya mengirimkan Anda cara yang benar berkaitan dengan enkapsulasi, SRP dan usabilitas ulang. Ini bukan hanya tentang mendapatkan beberapa tes di sekitar kode Anda: ini tentang menggunakan tes tersebut untuk menyempurnakan desain yang lebih baik. Jika suatu objek menciptakan dependensinya sendiri, maka ia hidup dalam konteks spesifik dalam aplikasi spesifik dan kemungkinan akan dijalin ke dalam aplikasi tersebut ke tingkat yang lebih besar. DI adalah hal yang baik, tidak hanya dari sudut pandang pengujian, tetapi juga dari sudut pandang kualitas kode.

Tim
sumber
Bisakah Anda mengklarifikasi bagian tidak dari jawaban ya dan tidak? Bagaimana cara melakukan TDD tanpa DI.
Gilles
Bagian 'tidak' adalah saya tidak berpikir itu adalah tautan langsung antara TDD dan DI. Ini tidak langsung melalui kualitas kode. Yang memecah rambut mungkin, tetapi hanya berpikir saya akan menunjukkan bahwa kualitas kode adalah hal yang Anda tuju, bukan hanya testabilitas.
Tim
0

Seperti yang sudah ditunjukkan dalam jawaban lain, TDD tidak memerlukan unit pengujian . Anda juga dapat menulis tes integrasi / fungsional saat melakukan TDD. Dari beberapa cara untuk menerapkan TDD, pembuatan unit test akan menjadi cara "berpura-pura sampai Anda berhasil" (lihat buku oleh Kent Beck untuk detailnya).

Adapun "TDD pasti mengarah ke DI", itu pasti tidak. Apa yang dibutuhkan seseorang ketika menulis unit test adalah mengisolasi unit yang sedang diuji dari implementasi dependensi eksternalnya. Dan ini dapat dilakukan dengan mudah dengan atau tanpa DI. Cara terbaik, mungkin, adalah dengan menggunakan alat isolasi / mengejek yang tepat.

Rogério
sumber
Tetapi untuk menggunakan ejekan, bukankah Anda harus menyuntikkan dependensi di kelas?
Gilles