Saya mencoba untuk menguji kelas yang memanggil beberapa layanan web Hadoop. Bentuknya hampir seperti:
method() {
...use Jersey client to create WebResource...
...make request...
...do something with response...
}
mis. ada metode buat direktori, metode buat folder dll.
Mengingat bahwa kode ini berurusan dengan layanan web eksternal yang tidak saya kendalikan, bagaimana saya bisa menguji unit ini? Saya bisa mencoba dan mengolok-olok klien layanan web / tanggapan tetapi itu melanggar pedoman yang saya lihat baru-baru ini: "Jangan mengejek objek yang tidak Anda miliki". Saya bisa mengatur implementasi layanan web dummy - apakah itu masih merupakan "unit test" atau apakah itu akan menjadi tes integrasi? Apakah tidak mungkin untuk menguji unit pada tingkat rendah ini - bagaimana praktisi TDD akan melakukan hal ini?
unit-testing
tdd
web-services
integration-tests
Chris Cooper
sumber
sumber
Jawaban:
Menurut pendapat saya, Anda harus mengejek panggilan layanan web jika ini adalah tes unit, bukan tes integrasi.
Tes unit Anda tidak boleh menguji apakah layanan web eksternal berfungsi, atau apakah integrasi Anda dengan layanan itu benar. Tanpa terlalu dogmatis tentang TDD, perhatikan bahwa efek samping dari mengubah tes unit Anda menjadi tes integrasi adalah bahwa hal itu cenderung berjalan lebih lambat, dan Anda ingin tes unit cepat .
Juga, jika layanan web sementara tidak berfungsi atau salah, haruskah ini menyebabkan unit test Anda gagal? Sepertinya tidak benar. Uji unit Anda harus gagal hanya karena satu alasan: jika ada bug dalam kode di "unit" itu.
Satu-satunya bagian dari kode yang relevan di sini adalah
...do something with response...
. Mengejek sisanya.sumber
Saya tidak setuju dengan "jangan mengejek objek yang tidak Anda miliki" saat Anda sedang menguji unit.
Tujuan keberadaan mengejek adalah kenyataan bahwa akan ada modul, perpustakaan, kelas yang tidak akan kita miliki.
Saran saya untuk skenario Anda adalah mengejek panggilan layanan web.
Siapkan tiruan sedemikian rupa sehingga mengembalikan data ke modul Anda.
Pastikan Anda mencakup semua skenario, misalnya ketika data yang dikembalikan kembali adalah nol, ketika data yang dikembalikan kembali valid, dll.
Dan untuk kode yang Anda miliki, tanggung jawab Anda sebagai pengembang adalah memastikan bahwa kode yang Anda tulis berkinerja seperti yang diharapkan dalam semua skenario.
sumber
Saya akan menggunakan sesuatu seperti EasyMock untuk tes ini. Kerangka kerja mengejek adalah cara yang ideal untuk menghapus dependensi luar di kelas dan memberi Anda kontrol total atas hasil dependensi luar selama tes. Untuk sedikit memperluas contoh Anda:
Hal pertama yang perlu Anda lakukan adalah mengekstrak logika di kelas Anda di mana Anda menggunakan Jersey untuk mendapatkan WebResource dan memanggil layanan web ke kelas yang terpisah. Membuat Antarmuka untuk kelas ini akan memungkinkan Anda untuk membuat tiruan yang kemudian dapat mendikte perilaku.
Setelah antarmuka ini dibuat, Anda dapat membuat tiruan menggunakan EasyMock, yang akan mengembalikan objek tertentu sesuai dengan kasus uji Anda. Contoh di atas adalah penyederhanaan bagaimana menyusun tes dasar yang diolok-olok dan bagaimana antarmuka Anda akan bekerja.
Untuk informasi lebih lanjut tentang kerangka kerja mengejek, silakan lihat pertanyaan ini . Juga, contoh ini mengasumsikan penggunaan Java tetapi kerangka kerja mengejek tersedia dalam semua bahasa dan meskipun mereka diterapkan secara berbeda, mereka akan bekerja secara umum dengan cara yang sama
sumber
Mengejek dapat diterima dalam kasus ini, tetapi Anda tidak membutuhkannya. Alih-alih pengujian unit
method()
, alih-alih pengujian unit hanya bagian yang menangani respons.Ekstrak fungsi yang mengambil
ResponseData
(dari jenis apa pun yang sesuai) dan kemudian melakukan tindakan.Alih-alih mengejek, sekarang Anda hanya membangun objek ResponseData dan meneruskannya.
Anda dapat meninggalkan panggilan layanan ke tes integrasi penuh - yang akan mencakup
method()
totalsumber
Apa yang telah saya lakukan, dan itu berhasil:
3.1. Pertama, semua layanan web diuji. Dari setiap mesin, bahkan mesin pengembang. Ini adalah layanan web nyata, tetapi berjalan di lingkungan pengembangan. Ini berarti layanan web tidak akan pernah bisa turun atau membalas nilai yang salah, karena jika tidak setiap pengembang mengeluh bahwa ia tidak dapat dikompilasi.
3.2 Kemudian semua tes unit internal ke aplikasi dijalankan. Ini berarti bahwa semua layanan web diejek dan diuji menjalankan tes yang sama dengan 3.1 (selain itu mereka harus lulus juga, jika tidak, tiruan itu salah), dan dipanggil oleh aplikasi nyata seolah-olah mereka benar-benar digunakan. Jika tiruannya salah, Anda dapat menjalankan tes di 3.1 dan mencatat nilai-nilai (permintaan, balas) di HashMap.
3.3 Kemudian tes yang sama seperti 3.2 dijalankan, tetapi kali ini terhadap layanan web nyata yang berjalan di lingkungan pengembangan.
Setelah semua ini selesai, untuk lingkungan produksi nyata Anda hanya perlu memberikan alamat asli untuk setiap layanan web. Semoga ini tidak memerlukan terlalu banyak perubahan dalam konfigurasi.
sumber