Introduction
REST-assured is a powerful Java library for testing RESTful web services. It simplifies the process of writing tests for REST APIs by providing a domain-specific language (DSL) for making HTTP requests and validating responses. In this tutorial, we will demonstrate how to use REST-assured to test a Spring Boot application, covering all CRUD operations.
Prerequisites
- Java Development Kit (JDK) 17 or later
- Apache Maven installed
- An IDE like IntelliJ IDEA or Eclipse
Step 1: Create a Spring Boot Project
You can create a Spring Boot project using Spring Initializr or your IDE.
Using Spring Initializr
- Go to Spring Initializr.
- Select the following options:
- Project: Maven Project
- Language: Java
- Spring Boot: 3.0.0 or later
- Group:
com.example
- Artifact:
rest-assured-demo
- Name:
rest-assured-demo
- Package name:
com.example.restassureddemo
- Packaging: Jar
- Java: 17 or later
- Add the following dependencies:
- Spring Web
- Spring Data JPA
- H2 Database
- Spring Boot Starter Test
- Click "Generate" to download the project zip file.
- Extract the zip file and open the project in your IDE.
Step 2: Add REST Assured Dependency
Add the following dependency to your pom.xml
file:
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.1.1</version>
<scope>test</scope>
</dependency>
Step 3: Configure Application Properties
Add the following properties to src/main/resources/application.properties
:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Step 4: Create the Entity Class
Create a new Java class named User
in the com.example.restassureddemo
package:
package com.example.restassureddemo;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Explanation: The User
class is a JPA entity that represents a user in our system. It has an id
, name
, and email
field. The @Entity
annotation specifies that this class is an entity and is mapped to a database table.
Step 5: Create the Repository Interface
Create a new Java interface named UserRepository
in the com.example.restassureddemo
package:
package com.example.restassureddemo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Explanation: The UserRepository
interface extends JpaRepository
, which provides JPA related methods for standard data access operations. This interface will be used to interact with the database.
Step 6: Create the Service Class
Create a new Java class named UserService
in the com.example.restassureddemo
package:
package com.example.restassureddemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User save(User user) {
return userRepository.save(user);
}
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
Explanation: The UserService
class contains methods for CRUD operations. It uses UserRepository
to interact with the database. The @Service
annotation indicates that this class is a service component in the Spring context.
Step 7: Create the Controller Class
Create a new Java class named UserController
in the com.example.restassureddemo
package:
package com.example.restassureddemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
return userService.findById(id)
.map(existingUser -> {
user.setId(existingUser.getId());
return ResponseEntity.ok(userService.save(user));
})
.orElse(ResponseEntity.notFound().build());
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return userService.findById(id)
.map(user -> {
userService.deleteById(id);
return ResponseEntity.noContent().build();
})
.orElse(ResponseEntity.notFound().build());
}
}
Explanation: The UserController
class handles HTTP requests and responses. It uses UserService
to perform CRUD operations.
The @RestController
annotation indicates that this class is a RESTful controller.
The @RequestMapping("/users")
annotation maps HTTP requests to /users
to the methods in this controller.
Step 8: Create the Main Application Class
Create a main application class named RestAssuredDemoApplication
in the com.example.restassureddemo
package:
package com.example.restassureddemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RestAssuredDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RestAssuredDemoApplication.class, args);
}
}
Explanation: The RestAssuredDemoApplication
class contains the main
method, which is the entry point of the Spring Boot application.
The @SpringBootApplication
annotation is a convenience annotation that adds all the following:
@Configuration
: Tags the class as a source of bean definitions for the application context.@EnableAutoConfiguration
: Tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.@ComponentScan
: Tells Spring to look for other components, configurations, and services in the specified package.
Step 9: Create REST Assured Tests
Create a new test class named UserControllerTest
in the src/test/java/com/example/restassureddemo
package:
package com.example.restassureddemo;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest {
@LocalServerPort
private int port;
@BeforeEach
public void setUp() {
RestAssured.port = port;
}
@Test
public void testCreateUser() {
given()
.contentType(ContentType.JSON)
.body(new User(null, "Amit Sharma", "amit.sharma@example.com"))
.when()
.post("/users")
.then()
.statusCode(201)
.body("id", notNullValue())
.body("name", equalTo("Amit Sharma"))
.body("email", equalTo("amit.sharma@example.com"));
}
@Test
public void testGetAllUsers() {
given()
.contentType(ContentType.JSON)
.when()
.get("/users")
.then()
.statusCode(200);
}
@Test
public void testGetUserById() {
Long userId = createUser("Ravi Kumar", "ravi.kumar@example.com");
given()
.contentType(ContentType.JSON)
.when()
.get("/users/{id}", userId)
.then()
.statusCode(200)
.body("id", equalTo(userId.intValue()))
.body("name", equalTo("Ravi Kumar"))
.body("email", equalTo("ravi.kumar@example.com"));
}
@Test
public void testUpdateUser() {
Long userId = createUser("Priya Singh", "priya.singh@example.com");
given()
.contentType(ContentType.JSON)
.body(new User(userId, "Priya Sharma", "priya.sharma@example.com"))
.when()
.put("/users/{id}", userId)
.then()
.statusCode(200)
.body("id", equalTo(userId.intValue()))
.body("name", equalTo("Priya Sharma"))
.body("email", equalTo("priya.sharma@example.com"));
}
@Test
public void testDeleteUser() {
Long userId = createUser("Neha Gupta", "neha.gupta@example.com");
given()
.contentType(ContentType.JSON)
.when()
.delete("/users/{id}", userId)
.then()
.statusCode(204);
}
private Long createUser(String name, String email) {
return given()
.contentType(ContentType.JSON)
.body(new User(null, name, email))
.when()
.post("/users")
.then()
.statusCode(201)
.extract()
.path("id");
}
}
Explanation: This test class uses REST-assured to test the CRUD operations of the UserController
.
Each test method performs a specific CRUD operation and verifies the response.
The @SpringBootTest
annotation tells Spring Boot to look for a main configuration class and use that to start a Spring application context.
The @LocalServerPort
annotation injects the port number the application is running on, and the @BeforeEach
method sets the port for REST-assured.
Step 10: Run the Tests
Run the tests using your IDE or by executing the following command in the terminal:
mvn test
You should see an output indicating that all tests have passed successfully.
Conclusion
In this tutorial, we demonstrated how to use REST-assured to test a Spring Boot application. We created a simple Spring Boot application with CRUD functionality, added REST-assured as a dependency, and wrote tests to validate the API endpoints.
By following these steps, you can efficiently test your Spring Boot applications and ensure that your REST APIs work as expected. This approach ensures robustness and reliability in your API endpoints, helping you catch issues early in the development process.
Comments
Post a Comment
Leave Comment