Uji REST API dengan Java

1. Ikhtisar

Tutorial ini berfokus pada prinsip dasar dan mekanisme pengujian REST API dengan Uji Integrasi langsung (dengan muatan JSON).

Tujuan utamanya adalah untuk memberikan pengantar untuk menguji kebenaran dasar API - dan kami akan menggunakan versi terbaru GitHub REST API sebagai contoh.

Untuk aplikasi internal, jenis pengujian ini biasanya akan berjalan sebagai langkah terakhir dalam proses Integrasi Berkelanjutan, menggunakan REST API setelah diterapkan.

Saat menguji sumber daya REST, biasanya ada beberapa tanggung jawab ortogonal yang harus difokuskan oleh pengujian:

  • kode tanggapan HTTP
  • header HTTP lain dalam tanggapannya
  • yang payload (JSON, XML)

Setiap pengujian sebaiknya hanya berfokus pada satu tanggung jawab dan mencakup satu pernyataan. Berfokus pada pemisahan yang jelas selalu memiliki manfaat, tetapi saat melakukan pengujian kotak hitam semacam ini bahkan lebih penting lagi, karena kecenderungan umumnya adalah menulis skenario pengujian yang rumit di awal.

Aspek penting lainnya dari pengujian integrasi adalah kepatuhan pada Prinsip Abstraksi Tingkat Tunggal - logika dalam pengujian harus ditulis pada tingkat tinggi. Detail seperti membuat permintaan, mengirim permintaan HTTP ke server, berurusan dengan IO, dll tidak boleh dilakukan secara inline tetapi melalui metode utilitas.

2. Menguji Kode Status

@Test public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived() throws ClientProtocolException, IOException { // Given String name = RandomStringUtils.randomAlphabetic( 8 ); HttpUriRequest request = new HttpGet( "//api.github.com/users/" + name ); // When HttpResponse httpResponse = HttpClientBuilder.create().build().execute( request ); // Then assertThat( httpResponse.getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_NOT_FOUND)); }

Ini adalah tes yang agak sederhana - ini memverifikasi bahwa jalur bahagia dasar berfungsi , tanpa menambahkan terlalu banyak kerumitan ke rangkaian pengujian.

Jika karena alasan apa pun, gagal, maka tidak perlu melihat tes lain untuk URL ini sampai ini diperbaiki.

3. Menguji Jenis Media

@Test public void givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson() throws ClientProtocolException, IOException { // Given String jsonMimeType = "application/json"; HttpUriRequest request = new HttpGet( "//api.github.com/users/eugenp" ); // When HttpResponse response = HttpClientBuilder.create().build().execute( request ); // Then String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType(); assertEquals( jsonMimeType, mimeType ); }

Ini memastikan bahwa Respons benar-benar berisi data JSON.

Seperti yang mungkin telah Anda perhatikan, kami mengikuti perkembangan pengujian yang logis - pertama Kode Status Respons (untuk memastikan bahwa permintaan itu OK), kemudian Jenis Media dari Respons, dan hanya di tes berikutnya kita akan melihat muatan JSON sebenarnya.

4. Menguji JSON Payload

@Test public void givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect() throws ClientProtocolException, IOException { // Given HttpUriRequest request = new HttpGet( "//api.github.com/users/eugenp" ); // When HttpResponse response = HttpClientBuilder.create().build().execute( request ); // Then GitHubUser resource = RetrieveUtil.retrieveResourceFromResponse( response, GitHubUser.class); assertThat( "eugenp", Matchers.is( resource.getLogin() ) ); }

Dalam kasus ini, saya tahu representasi default dari sumber daya GitHub adalah JSON, tetapi biasanya, header Content-Type dari respons harus diuji di samping header Terima permintaan - klien meminta jenis representasi tertentu melalui Terima , yang mana server harus menghormati.

5. Utilitas untuk Pengujian

Kita akan menggunakan Jackson 2 untuk mengurai String JSON mentah menjadi Entitas Java yang aman bagi tipe:

public class GitHubUser { private String login; // standard getters and setters }

Kami hanya menggunakan utilitas sederhana untuk menjaga pengujian tetap bersih, dapat dibaca, dan pada tingkat abstraksi yang tinggi:

public static  T retrieveResourceFromResponse(HttpResponse response, Class clazz) throws IOException { String jsonFromResponse = EntityUtils.toString(response.getEntity()); ObjectMapper mapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper.readValue(jsonFromResponse, clazz); }

Perhatikan bahwa Jackson mengabaikan properti yang tidak diketahui yang dikirim oleh GitHub API - itu hanya karena Representasi Sumber Daya Pengguna di GitHub menjadi sangat rumit - dan kami tidak memerlukan informasi tersebut di sini.

6. Ketergantungan

Utilitas dan pengujian menggunakan pustaka berikut, semuanya tersedia di pusat Maven:

  • HttpClient
  • Jackson 2
  • Hamcrest (opsional)

7. Kesimpulan

Ini hanya satu bagian dari apa yang seharusnya menjadi rangkaian pengujian integrasi lengkap. Tes fokus pada memastikan ketepatan dasar untuk REST API , tanpa masuk ke skenario yang lebih kompleks,

Misalnya, berikut ini tidak tercakup: API untuk ditemukan, konsumsi representasi berbeda untuk Sumber Daya yang sama, dll.

Penerapan semua contoh dan cuplikan kode ini dapat ditemukan di Github - ini adalah proyek berbasis Maven, jadi semestinya mudah untuk mengimpor dan menjalankan apa adanya.