Menjelajahi Kerangka Uji Jersey

1. Ikhtisar

Dalam tutorial ini, kita akan melihat Kerangka Uji Jersey dan melihat bagaimana kita dapat menggunakannya untuk menulis tes integrasi dengan cepat.

Seperti yang telah kita lihat di artikel sebelumnya, Jersey adalah kerangka kerja sumber terbuka untuk mengembangkan Layanan Web RESTful . Kita dapat mempelajari lebih lanjut tentang Jersey dalam pengantar kami untuk membuat API dengan artikel Jersey dan Musim Semi - di sini.

2. Pengaturan Aplikasi

Kerangka Kerja Uji Jersey adalah alat untuk membantu kami memverifikasi penerapan yang benar dari komponen sisi server kami. Seperti yang akan kita lihat nanti, ini menyediakan cara yang cepat dan bebas repot untuk menulis tes integrasi dan dapat menangani komunikasi dengan API HTTP kita dengan sangat baik.

Demikian pula, ini bekerja hampir di luar kotak dan mudah untuk diintegrasikan dengan proyek berbasis Maven kami . Kerangka kerja ini terutama didasarkan pada JUnit meskipun dimungkinkan untuk digunakan dengan TestNG juga yang membuatnya dapat digunakan di hampir semua lingkungan.

Di bagian selanjutnya, kita akan melihat dependensi mana yang perlu kita tambahkan ke aplikasi kita untuk menggunakan framework.

2.1. Dependensi Maven

Pertama-tama, mari tambahkan dependensi inti Jersey Test Framework ke pom.xml kami :

 org.glassfish.jersey.test-framework jersey-test-framework-core 2.27 test 

Seperti biasa, kami bisa mendapatkan versi terbaru dari Maven Central.

Hampir semua pengujian Jersey menggunakan pabrik kontainer uji Grizzly defacto, yang juga perlu kami tambahkan:

 org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-grizzly2 2.27 test 

Sekali lagi kami dapat menemukan versi terbaru di Maven Central.

3. Memulai

Di bagian selanjutnya, kita akan membahas langkah-langkah dasar yang diperlukan untuk menulis tes sederhana.

Kami akan mulai dengan menguji sumber daya Salam sederhana di server kami:

@Path("/greetings") public class Greetings { @GET @Path("/hi") public String getHiGreeting() { return "hi"; } } 

3.1. Mengonfigurasi Tes

Sekarang mari kita tentukan kelas pengujian kita:

public class GreetingsResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { return new ResourceConfig(Greetings.class); } //... } 

Kita dapat melihat pada contoh di atas bahwa untuk mengembangkan tes menggunakan Jersey Test Framework, tes kita perlu subclass JerseyTest .

Selanjutnya, kami mengganti metode konfigurasi yang mengembalikan konfigurasi sumber daya khusus untuk pengujian kami dan hanya berisi sumber daya Salam . Ini, tentu saja, sumber daya yang ingin kami uji.

3.2. Menulis Tes Pertama Kami

Mari kita mulai dengan menguji permintaan GET sederhana dari API salam kami:

@Test public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() { Response response = target("/greetings/hi").request() .get(); assertEquals("Http Response should be 200: ", Status.OK.getStatusCode(), response.getStatus()); assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE)); String content = response.readEntity(String.class); assertEquals("Content of ressponse is: ", "hi", content); } 

Perhatikan bahwa kita memiliki akses penuh ke respons HTTP - jadi kami dapat melakukan hal-hal seperti memeriksa kode status untuk memastikan operasi benar-benar berhasil, atau bekerja dengan isi respons yang sebenarnya .

Mari kita jelaskan lebih detail apa yang kami lakukan pada contoh di atas:

  1. Kirim permintaan HTTP GET ke '/ greetings / hi'
  2. Periksa kode status HTTP dan header respons tipe konten
  3. Uji isi respon yang mengandung string “hai”

4. Menguji GET untuk Mengambil Sumber Daya

Sekarang, kita telah melihat langkah-langkah dasar yang terlibat dalam pembuatan tes. Mari kita uji API Buah sederhana yang kami perkenalkan di artikel Dukungan MVC Jersey yang sangat baik.

4.1. Dapatkan JSON Biasa

Dalam contoh di bawah ini kami bekerja dengan badan respons sebagai String JSON standar:

@Test public void givenFruitExists_whenSearching_thenResponseContainsFruit() { final String json = target("fruit/search/strawberry").request() .get(String.class); assertThat(json, containsString("{\"name\":\"strawberry\",\"weight\":20}")); }

4.2. Dapatkan Entitas, Bukan JSON

We can also map the response directly to a Resource entity class – for example:

 @Test public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() { final Fruit entity = target("fruit/search/strawberry").request() .get(Fruit.class); assertEquals("Fruit name: ", "strawberry", entity.getName()); assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight()); }

This time, we specify the Java type the response entity will be converted to in the get method – a Fruit object.

5. Testing POST to Create Resources

In order to create a new Resource in our API – we will make good use of POST requests. In the next section, we'll see how to test this part of our API.

5.1. Post Plain JSON

Let's start by posting a plain JSON String to test the creation of a new fruit resource:

@Test public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() { Response response = target("fruit/created").request() .post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}")); assertEquals("Http Response should be 201 ", Status.CREATED.getStatusCode(), response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]")); }

In the above example, we make use of the post method which takes an Entity object parameter. We use the convenient json method to create an entity from the corresponding JSON string.

5.2. Post Entity Instead of JSON

As we've already seen with get requests we can also post a Resource entity class directly – for example:

@Test public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { Fruit fruit = new Fruit("Blueberry", "purple"); fruit.setWeight(1); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); assertEquals("Http Response should be 400 ", 400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater")); }

This time we use the entity method to post our Fruit entity and also specify the media type as JSON.

5.3. Form Submissions Using POST

In our final post example we will see how to test form submissions via a post request:

@Test public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { Form form = new Form(); form.param("name", "apple"); form.param("colour", null); Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED) .post(Entity.form(form)); assertEquals("Http Response should be 400 ", 400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null")); }

Similarly, we make use of the Entity class but this time pass a form which contains a number of parameters to our post request.

6. Testing Other HTTP Verbs

Sometimes we need to test other HTTP endpoints such as PUT and DELETE. This is of course perfectly possible using the Jersey Test Framework.

Let's see a simple PUT example:

@Test public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { Form form = new Form(); form.param("serial", "2345-2345"); Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED) .put(Entity.form(form)); assertEquals("Http Response should be 400 ", 400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid")); }

Once we have called the request method, we can invoke any HTTP method on the current request object.

7. Additional Features

The Jersey test framework contains a number of additional configuration properties which can help aid debugging and testing.

In the next example we'll see how to programmatically enable a feature with a given name:

public class FruitResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { enable(TestProperties.LOG_TRAFFIC); enable(TestProperties.DUMP_ENTITY); //...

When we create and configure our Jersey application under test. We can also enable additional properties. In this case, we enable two logging properties – LOG_TRAFFIC and DUMP_ENTITYwhich will provide useful additional logging and debug information during test runs.

8. Supported Containers

As we've already mentioned the defacto container used when writing tests with the Jersey Test Framework is Grizzly. However, a number of other containers are supported:

  • In-Memory container
  • HttpServer from Oracle JDK
  • Simple container (org.simpleframework.http
  • Jetty container (org.eclipse.jetty)

For more information on how to configure these containers, please see the documentation here.

9. Conclusion

To summarize, in this tutorial, we’ve explored the Jersey Test Framework. First, we started by introducing how to configure the Jersey Test Framework and then we saw how to write a test for a very simple API.

In the next section, we saw how to write tests for a variety of GET and POST API endpoints. Finally, we looked at some additional features and the containers that the Jersey Test Framework supports.

Seperti biasa, kode sumber lengkap artikel tersedia di GitHub.