GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Webservice REST Test REST Web Service đơn giản hơn với REST Assured

Test REST Web Service đơn giản hơn với REST Assured

Đăng vào 26/08/2019 . Được đăng bởi GP Coder . 5854 Lượt xem . Toàn màn hình

Ở bài viết trước, tôi đã giới thiệu với các bạn cách test REST API trong Jersey project. Giả sử bây giờ chúng ta cần sử dụng API của bên thứ 3 (không phải source code trong jersey project của chúng ta), khi đó ta không thể sử dụng Jersey Test. Khi đó, chúng ta cần một thư viện khác có thể giúp chúng ta gửi một request thật để verfiy kết quả trả về.

Trong bài này tôi sẽ giới thiệu với các bạn một thư viện rất mạnh mẽ để test web service, đó chính là REST Assured. Nó cho phép chúng ta gửi một HTTP request thật và verify trên kết quả trả về một cách dễ dàng. Chẳng hạn chúng ta có một request http://localhost:8080/lotto/{id} và server trả về response JSON như sau:

Khi đó chúng ta dễ dàng sử dụng REST Assured để verify mọi thứ từ response trên như sau:

Mọi thứ trông thật đơn giản phải không nào? Bây giờ, chúng ta hãy bắt đầu cài đặt thư viện cần thiết và viết một vài test case cho REST API sử dụng REST Assured.

Nội dung

  • 1 Cài đặt REST Assured
  • 2 Xây dựng Jersey Rest API
  • 3 Test REST API sử dụng REST Assured

Cài đặt REST Assured

Để sử dụng REST Assured chúng ta đơn giản chỉ việc thêm dependency sau trong file pom.xml.


<!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>4.0.0</version>
</dependency>

Mặc định, REST Assured đã bao gồm 2 thư viện khác là JsonPath và XmlPath giúp chúng ta dễ dàng verify Json và Xml response.

Ngoài ra, các bạn có thể thêm thư viện JUnit và Mockito nếu cần thiết.

  • https://mvnrepository.com/artifact/junit/junit
  • https://mvnrepository.com/artifact/org.mockito/mockito-core

Xây dựng Jersey Rest API

Bước này chỉ là giả định bên thứ ba cung cấp cho chúng ta các API để sử dụng, nếu các bạn đã có sẵn REST API, các bạn có thể đi đến bước kế tiếp “Test REST API sử dụng REST Assured”.

Để dễ hiểu, tôi sử dụng lại service đã tạo ở bài trước để hướng dẫn các bạn viết JUnit Test cho REST API với REST Assured.

Chúng ta có các API sau:

Giả sử tất cả các API này user cần phải được chứng thực trước. Tôi sẽ sử dụng Basic Authentication với JWT. Chi tiết các bạn xem lại bài viết “JWT – Token-based Authentication trong Jersey 2.x“.

Chúng ta có class AuthService như sau:


package com.gpcoder.api;

import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.gpcoder.helper.JwTokenHelper;
import com.gpcoder.model.User;
import com.gpcoder.service.UserService;

@Path("/auth")
public class AuthService {

	@POST
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response authenticateUser(@FormParam("username") String username, @FormParam("password") String password) {

		// Authenticate the user using the credentials provided
		UserService userService = new UserService();
		User user = userService.getUser(username);
		if (user == null || !user.getPassword().equals(password)) {
			return Response.status(Response.Status.FORBIDDEN) // 403 Forbidden
					.entity("Wrong username or password") // the response entity
					.build();
		}

		// Issue a token for the user
		String token = JwTokenHelper.createJWT(user);

		// Return the token on the response
		return Response.ok(token).build();
	}
}

Class OrderService cần thêm Annotation Authorized của Jersey @RolesAllowed(Role.ROLE_ADMIN)


package com.gpcoder.api;

import javax.annotation.security.RolesAllowed;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.SecurityContext;

import com.gpcoder.model.Order;
import com.gpcoder.model.Role;

// URI:
// http(s)://<domain>:(port)/<YourApplicationName>/<UrlPattern in web.xml>/<path>
// http://localhost:8080/api/orders
@Path("/orders")
@RolesAllowed(Role.ROLE_ADMIN)
public class OrderService {

	@GET
	@Path("/{id}")
	public Response get(@PathParam("id") int id) {
		Order order = new Order();
		order.setId(1);
		order.setName("gpcoder");
		return Response.ok(order).build();
	}

	@POST
	public Response insert(Order order, @Context SecurityContext securityContext) {
		int newOrderId = 999;
		return Response.status(Status.CREATED).entity(newOrderId).build();
	}

	@PUT
	@Path("/{id}")
	public Response update(@PathParam("id") int id, Order order) {
		return Response.ok().build();
	}

	@DELETE
	@Path("/{id}")
	public Response delete(@PathParam("id") int id) {
		return Response.status(Status.NO_CONTENT).build();
	}
}

Test REST API sử dụng REST Assured

Do các API cần phải được chứng thực user trước khi sử dụng, nên chúng ta cần chứng thực trước để nhận một Token (JWT), sau đó gửi chúng vào header ở mỗi request.

  • getBearerToken() : gửi request authentication để lấy token (JWT).
  • testGetById_Way1() : sử dụng để test GET /api/orders/{id}, trong ví dụ này tôi sẽ verify trực tiếp response thông qua phương thức body của REST Assured.
  • testGetById_Way2() : sử dụng để test GET /api/orders/{id}, trong ví dụ này tôi sẽ tạo một POJO object để nhận response và verify kết quả thông qua các phương thức của JUnit.
  • testCreate() : sử dụng để test POST /api/orders
  • testUpdate() : sử dụng để test PUT /api/orders/{id}
  • testDelete() : sử dụng để test DELETE /api/orders/{id}

OrderServiceRestAssuredTest.java


package com.gpcoder.api;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

import javax.ws.rs.core.Response.Status;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.gpcoder.model.Order;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;

public class OrderServiceRestAssuredTest {
	
	private static String BEARER_TOKEN = "";
	
	@BeforeClass
	public static void setUp() {
		RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
		RestAssured.baseURI = "http://localhost";
        RestAssured.port = 8080;
        BEARER_TOKEN = getBearerToken();
	}
	
	public static String getBearerToken() {
		Response response = 
			given()
				.header("Content-Type", "application/x-www-form-urlencoded")
				.formParam("username", "gpcoder")
				.formParam("password", "gpcoder")
				.request()
			.when()
				.post("/api/auth")
			.then()
				.assertThat()
				.statusCode(Status.OK.getStatusCode())
				.extract()
				.response();
		return response.asString();
		
	}

	@Test
	public void testGetById_Way1() {
		given()
			.headers("Authorization", "Bearer " + BEARER_TOKEN)
			.accept(ContentType.JSON)
		.when()
			.get("/api/orders/1")
		.then()
			.statusCode(Status.OK.getStatusCode())
          	.contentType(ContentType.JSON)
          	.body("id", equalTo(1)) // Verify JSON Path
          	.body("name", equalTo("gpcoder"));
	}

	@Test
	public void testGetById_Way2() {
		Order order = 
			given()
				.headers("Authorization", "Bearer " + BEARER_TOKEN)
				.accept(ContentType.JSON)
			.when()
				.get("/api/orders/1")
			.then()
				.statusCode(Status.OK.getStatusCode())
	          	.contentType(ContentType.JSON)
	          	.extract().as(Order.class); // Use POJOs and Object Mapping
		
		Assert.assertEquals(1, order.getId().intValue());
		Assert.assertEquals("gpcoder", order.getName());
	}

	@Test
	public void testCreate() {
		Order order = new Order(1, "gpcoder");
		
		Integer newOrderId =
			given()
				.headers("Authorization", "Bearer " + BEARER_TOKEN)
				.contentType(ContentType.JSON)
				.accept(ContentType.JSON)
				.body(order)
			.when()
				.post("/api/orders")
			.then()
				.assertThat()
				.statusCode(Status.CREATED.getStatusCode())
				.extract().as(Integer.class);
		
		Assert.assertEquals(999, newOrderId.intValue());
	}

	@Test
	public void testUpdate() {
		Order order = new Order(1, "gpcoder edited");
		given()
			.headers("Authorization", "Bearer " + BEARER_TOKEN)
			.contentType(ContentType.JSON)
			.body(order)
		.when()
			.put("/api/orders/{id}/", order.getId())
		.then()
			.assertThat()
			.statusCode(Status.OK.getStatusCode());
	}

	@Test
	public void testDelete() {
		given()
			.headers("Authorization", "Bearer " + BEARER_TOKEN)
		.when()
			.delete("/api/orders/{id}/", 1)
		.then()
			.assertThat()
			.statusCode(Status.NO_CONTENT.getStatusCode());
	}
}


Các bạn có thể chạy thử để xem kết quả.

Lưu ý: Phải start server REST API lên trước khi chạy Unit Test.

Như bạn thấy, REST Assured hỗ trợ cú pháp rất quen thuộc từ Behavior-Driven Development (BDD) khi viết Unit Test là Given/ When/ Then. Nhờ vậy mà Unit test của chúng ta rất dễ đọc và dễ kiểm tra tất cả mọi thứ (setup, execution, and verification) với chỉ vài dòng code.

  • Given: Thiết lập các điều kiện cần thiết: khởi tạo các đối tượng, xác định tài nguyên cần thiết, xây dựng các dữ liệu giả, …
  • When: Triệu gọi các phương thức cần kiểm tra.
  • Then: Kiểm tra sự hoạt động đúng đắn của các phương thức.

Trên đây là một số ví dụ cơ bản về viết Unit Test cho REST web server sử dụng thư viện REST Assured, còn rất nhiều phương thức khác hỗ trợ chúng ta viết test dễ dàng hơn và nhanh chóng hơn, các bạn hãy tham khảo thêm trên document của REST Assured.

Tài liệu tham khảo:

  • http://rest-assured.io/
  • https://github.com/rest-assured/rest-assured
  • https://github.com/rest-assured/rest-assured/wiki/Usage
  • https://www.baeldung.com/rest-assured-tutorial
  • https://www.baeldung.com/rest-assured-header-cookie-parameter
  • https://www.baeldung.com/rest-assured-authentication
5.0
11
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Java Webservice, REST, Unit Test Được gắn thẻ: JUnit, REST, Unit Test, Webservice

Làm thế nào để Test Jersey Rest API với JUnit?
Triển khai ứng dụng Jersey REST Web service lên Tomcat Server

Có thể bạn muốn xem:

  • REST Web service: JWT – Token-based Authentication trong Jersey 2.x (10/07/2019)
  • Giới thiệu Castle Mock – Mock REST APIs và SOAP web-services (05/09/2019)
  • Triển khai ứng dụng Jersey REST Web service lên Tomcat Server (29/08/2019)
  • SOAP Web service: Upload và Download file sử dụng MTOM trong JAX-WS (06/06/2019)
  • Tạo ứng dụng Java RESTful Client không sử dụng 3rd party libraries (12/07/2019)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (98133 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97756 lượt xem)
  • Giới thiệu Design Patterns (87906 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (86531 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83930 lượt xem)

Nội dung bài viết

  • 1 Cài đặt REST Assured
  • 2 Xây dựng Jersey Rest API
  • 3 Test REST API sử dụng REST Assured

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link