Saya menggunakan Mockito dalam beberapa tes.
Saya memiliki kelas-kelas berikut:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
Saya hanya ingin mengejek panggilan kedua ( super.save
) dari ChildService
. Panggilan pertama harus memanggil metode sebenarnya. Apakah ada cara untuk melakukannya?
Jawaban:
Tidak, Mockito tidak mendukung ini.
Ini mungkin bukan jawaban yang Anda cari, tetapi yang Anda lihat adalah gejala tidak menerapkan prinsip desain:
Jika Anda mengekstrak strategi alih-alih memperluas kelas super, masalahnya hilang.
Namun jika Anda tidak diizinkan untuk mengubah kode, tetapi Anda harus tetap mengujinya, dan dengan cara yang canggung ini, masih ada harapan. Dengan beberapa alat AOP (misalnya AspectJ) Anda dapat memasukkan kode ke dalam metode kelas super dan menghindari eksekusi sepenuhnya (yuck). Ini tidak berfungsi jika Anda menggunakan proxy, Anda harus menggunakan modifikasi bytecode (baik waktu muat menenun atau mengompilasi waktu tenun). Ada kerangka kerja tiruan yang mendukung jenis trik ini juga, seperti PowerMock dan PowerMockito.
Saya sarankan Anda pergi untuk refactoring, tetapi jika itu bukan pilihan Anda berada dalam kesenangan hacking yang serius.
sumber
//some codes
kode tersebut menjadi metode yang dapat diuji secara terpisah.Jika Anda benar-benar tidak memiliki pilihan untuk refactoring, Anda dapat membuat tiruan / stub semuanya dalam pemanggilan metode super mis
sumber
BaseService
abstrak, meskipun saya tidak mengerti mengapa hal itu relevan.super.validate()
Pertimbangkan untuk memfaktorkan ulang kode dari metode ChildService.save () ke metode yang berbeda dan uji metode baru tersebut daripada menguji ChildService.save (), dengan cara ini Anda akan menghindari panggilan yang tidak perlu ke metode super.
Contoh:
sumber
buat metode yang dilindungi paket (anggap kelas pengujian dalam paket yang sama) di sub kelas yang memanggil metode kelas super dan kemudian panggil metode itu dalam metode sub kelas yang diganti. Anda kemudian dapat menetapkan ekspektasi pada metode ini dalam pengujian Anda melalui penggunaan pola mata-mata. tidak cantik tapi pasti lebih baik daripada harus berurusan dengan semua pengaturan harapan untuk metode super dalam pengujian Anda
sumber
Bahkan jika saya setuju dengan tanggapan iwein (
), saya akui ada beberapa kali pewarisan tampak wajar, dan saya tidak merasa rusak atau refactor hanya demi tes unit.
Jadi, saran saya:
Dan kemudian, dalam pengujian unit:
sumber
Alasannya adalah kelas dasar Anda tidak bersifat publik, maka Mockito tidak dapat mencegatnya karena visibilitas, jika Anda mengubah kelas dasar sebagai publik, atau @Override di sub kelas (sebagai publik), maka Mockito dapat memalsukannya dengan benar.
sumber
Mungkin opsi termudah jika warisan masuk akal adalah dengan membuat metode baru (paket pribadi ??) untuk memanggil super (sebut saja superFindall), mata-matai contoh nyata dan kemudian tiru metode superFindAll () dengan cara yang Anda inginkan untuk mengejek kelas orang tua satu. Ini bukan solusi sempurna dalam hal cakupan dan visibilitas tetapi harus melakukan pekerjaan itu dan mudah untuk diterapkan.
sumber