Uji REST API dengan Java

1. Gambaran keseluruhan

Tutorial ini memberi tumpuan kepada prinsip dan mekanik asas menguji REST API dengan Ujian Integrasi langsung (dengan muatan JSON).

Matlamat utama adalah memberi pengenalan untuk menguji kebenaran asas API - dan kami akan menggunakan versi terbaru API GitHub REST untuk contohnya.

Untuk aplikasi dalaman, pengujian semacam ini biasanya akan dijalankan sebagai langkah akhir dalam proses Integrasi Berterusan, memakan API REST setelah aplikasi tersebut telah digunakan.

Semasa menguji sumber REST, biasanya terdapat beberapa tanggungjawab ortogonal yang harus difokuskan oleh ujian:

  • kod respons HTTP
  • tajuk HTTP yang lain sebagai tindak balas
  • yang muatan (JSON, XML)

Setiap ujian hanya boleh memfokus pada satu tanggungjawab dan merangkumi satu penegasan. Memusatkan perhatian pada pemisahan yang jelas selalu memberi faedah, tetapi ketika melakukan ujian kotak hitam semacam ini lebih penting lagi, kerana kecenderungan umum adalah menulis senario ujian yang kompleks pada awalnya.

Aspek lain yang penting dalam ujian integrasi adalah mematuhi Prinsip Abstraksi Tahap Tunggal - logik dalam ujian harus ditulis pada tahap tinggi. Perincian seperti membuat permintaan, mengirim permintaan HTTP ke pelayan, berurusan dengan IO, dll tidak boleh dilakukan sebaris tetapi melalui kaedah utiliti.

2. Menguji Kod 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 ujian yang agak mudah - ia mengesahkan bahawa jalan senang asas berfungsi , tanpa menambahkan kerumitan terlalu banyak pada rangkaian ujian.

Sekiranya atas sebab apa pun, ia gagal, maka tidak perlu melihat ujian lain untuk URL ini sehingga 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 bahawa Respons benar-benar mengandungi data JSON.

Seperti yang anda perhatikan, kami mengikuti perkembangan ujian yang logik - pertama Kod Status Respons (untuk memastikan bahawa permintaan itu OK), kemudian Jenis Media Respons, dan hanya dalam ujian seterusnya kita akan melihat muatan JSON sebenar.

4. Menguji Beban JSON

@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 kes ini, saya tahu perwakilan lalai sumber GitHub adalah JSON, tetapi biasanya, tajuk Jenis Isi respons harus diuji bersama dengan tajuk Terima permintaan - pelanggan meminta jenis perwakilan tertentu melalui Accept , yang pelayan harus menghormati.

5. Utiliti untuk Ujian

Kami akan menggunakan Jackson 2 untuk mencabut JSON String mentah ke dalam Entiti Java yang selamat.

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

Kami hanya menggunakan utiliti sederhana untuk memastikan ujian tetap bersih, mudah dibaca dan pada tahap pengabstrakan 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 bahawa Jackson mengabaikan sifat yang tidak diketahui yang dihantar oleh API GitHub - itu hanya kerana Perwakilan Sumber Pengguna di GitHub menjadi sangat rumit - dan kami tidak memerlukan maklumat tersebut di sini.

6. Kebergantungan

Utiliti dan ujian menggunakan perpustakaan berikut, semuanya terdapat di Maven central:

  • Pelanggan Http
  • Jackson 2
  • Hamcrest (pilihan)

7. Kesimpulannya

Ini hanya satu bahagian dari rangkaian ujian integrasi lengkap. Ujian menumpukan pada memastikan kebenaran asas untuk REST API , tanpa menjalani senario yang lebih kompleks,

Contohnya, perkara berikut tidak diliputi: Kebolehcapaian API, penggunaan representasi yang berbeza untuk Sumber yang sama, dll.

Pelaksanaan semua contoh dan coretan kod ini dapat dilihat di Github - ini adalah projek berasaskan Maven, jadi mudah diimport dan dijalankan sebagaimana adanya.