Saya memiliki implementasi kerangka, seperti pada Butir 18 dari Java Efektif (diskusi diperpanjang di sini ). Ini adalah kelas abstrak yang menyediakan 2 metode metode publik, methodA () dan methodB () yang memanggil metode subclass untuk "mengisi kesenjangan" yang tidak bisa saya definisikan secara abstrak.
Saya mengembangkannya terlebih dahulu dengan membuat kelas konkret dan menulis unit test untuknya. Ketika kelas kedua datang, saya dapat mengekstraksi perilaku umum, mengimplementasikan "celah yang hilang" di kelas kedua dan siap (tentu saja, unit test dibuat untuk subclass kedua).
Waktu berlalu dan sekarang saya memiliki 4 subclass, masing-masing menerapkan 3 metode terproteksi pendek yang sangat spesifik untuk implementasi konkretnya, sementara implementasi kerangka melakukan semua pekerjaan umum.
Masalah saya adalah ketika saya membuat implementasi baru, saya menulis semua tes lagi:
- Apakah subclass memanggil metode yang diperlukan?
- Apakah metode yang diberikan memiliki anotasi yang diberikan?
- Apakah saya mendapatkan hasil yang diharapkan dari metode A?
- Apakah saya mendapatkan hasil yang diharapkan dari metode B?
Sambil melihat manfaat dengan pendekatan ini:
- Ini mendokumentasikan persyaratan subkelas melalui tes
- Ini mungkin gagal cepat jika terjadi refactoring yang bermasalah
- Uji subclass secara keseluruhan dan melalui API publik mereka ("apakah methodA () berfungsi?" Dan tidak "apakah metode yang dilindungi ini berfungsi?")
Masalah yang saya miliki adalah bahwa tes untuk subclass baru pada dasarnya adalah no-brainer: - Tes semua sama di semua subclass, mereka hanya mengubah jenis pengembalian metode (implementasi kerangka adalah generik) dan properti I periksa bagian tegas dari tes. - Biasanya subclass tidak memiliki tes yang khusus untuk mereka
Saya suka cara tes fokus pada hasil subclass itu sendiri dan melindunginya dari refactoring, tetapi kenyataan bahwa pelaksanaan tes menjadi hanya "pekerjaan manual" membuat saya berpikir saya melakukan sesuatu yang salah.
Apakah masalah ini umum ketika menguji hierarki kelas? Bagaimana saya bisa menghindarinya?
ps: Saya berpikir untuk menguji kelas kerangka, tetapi juga aneh membuat tiruan dari kelas abstrak untuk dapat mengujinya. Dan saya berpikir bahwa setiap refactoring pada kelas abstrak yang mengubah perilaku yang tidak diharapkan oleh subclass tidak akan diperhatikan secepat ini. Nyali saya memberi tahu saya bahwa menguji subclass "secara keseluruhan" adalah pendekatan yang lebih disukai di sini, tetapi jangan ragu untuk memberi tahu saya bahwa saya salah :)
ps2: Saya sudah mencari di Google dan menemukan banyak pertanyaan tentang subjek ini. Salah satunya adalah ini yang memiliki jawaban bagus dari Nigel Thorne, kasus saya akan menjadi "nomor 1." Itu bagus, tapi saya tidak bisa menolak pada saat ini, jadi saya harus hidup dengan masalah ini. Jika saya bisa refactor, saya akan memiliki masing-masing subclass sebagai strategi. Itu akan baik-baik saja, tetapi saya masih akan menguji "kelas utama" dan menguji strategi, tetapi saya tidak akan melihat adanya refactoring yang merusak integrasi antara kelas utama dan strategi.
ps3: Saya telah menemukan beberapa jawaban yang mengatakan bahwa "dapat diterima" untuk menguji kelas abstrak. Saya setuju bahwa ini dapat diterima, tetapi saya ingin tahu pendekatan mana yang lebih disukai dalam kasus ini (saya masih mulai dengan unit test)