Khóa học spring-boot

Ví dụ về testing trong Spring Boot

0 phút đọc

Testing là một phần quan trọng trong quá trình phát triển ứng dụng để đảm bảo rằng mã nguồn của bạn hoạt động đúng và ổn định. Trong bài viết này, chúng ta sẽ tìm hiểu cách thực hiện testing trong Spring Boot bằng Java, với sự hỗ trợ của Hibernate, Spring JPA, Lombok và Spring Boot.

Chuẩn bị Dự Án

Đầu tiên, hãy tạo một dự án Spring Boot đơn giản. Dưới đây là một ví dụ về pom.xml để sử dụng các dependency cần thiết:

xml Copy
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/>
    </parent>
    <groupId>me.kungfutech.spring</groupId>
    <artifactId>example-independent-maven-spring-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>example-independent-maven-spring-project</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring JPA -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- In-memory database -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Sau khi tạo dự án, hãy thêm các class cơ bản sau:

Todo.java

java Copy
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Todo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String title;
    private String detail;
}

TodoRepository.java

java Copy
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface TodoRepository extends JpaRepository<Todo, Long> {
    List<Todo> findAll();

    Todo findById(int id);
}

TodoController.java

java Copy
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
public class TodoRestController {
    private final TodoService todoService;

    @GetMapping("/todo")
    public List<Todo> findAll() {
        return todoService.getAll();
    }
}

DataJpaAnnotationTest.java

java Copy
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.persistence.EntityManager;
import javax.sql.DataSource;

@RunWith(SpringRunner.class)
@DataJpaTest
public class DataJpaAnnotationTest {
    @Autowired
    private DataSource dataSource;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private EntityManager entityManager;
    @Autowired
    private TodoRepository todoRepository;

    @Test
    public void allComponentAreNotNull() {
        Assertions.assertThat(dataSource).isNotNull();
        Assertions.assertThat(jdbcTemplate).isNotNull();
        Assertions.assertThat(entityManager).isNotNull();
        Assertions.assertThat(todoRepository).isNotNull();
    }
}

Testing với @DataJpaTest

Testing một ứng dụng Spring Boot có thể phức tạp, đặc biệt là khi liên quan đến cơ sở dữ liệu. Tuy nhiên, chúng ta có thể sử dụng @DataJpaTest để giới hạn phạm vi testing. @DataJpaTest sẽ giúp chúng ta tạo ra môi trường test cho các tầng Repository mà không cần khởi động toàn bộ ứng dụng Spring Boot.

Trong ví dụ trên, chúng ta đã test các thành phần liên quan đến cơ sở dữ liệu như DataSource, JdbcTemplate, EntityManager, và TodoRepository. @DataJpaTest sẽ khởi tạo các Bean liên quan đến tầng Repository, giúp bạn kiểm tra chúng một cách dễ dàng.

Chuẩn bị Dữ Liệu Test

Trong thực tế, chúng ta không thể mãi mãi sử dụng dữ liệu giả mạo cho các test case. Điều này có thể tạo ra một lỗ hổng lớn trong kiểm thử của bạn. Bên cạnh đó, bạn cũng muốn kiểm tra quá trình tương tác với cơ sở dữ liệu thật của ứng dụng của bạn.

Spring Boot đã cung cấp một số cách để chuẩn bị dữ liệu cho các test case.

Tạo Dữ Liệu Giả Mạo

Một cách đơn giản để chuẩn bị dữ liệu giả mạo là tự thêm dữ liệu bằng cách sử dụng repository. Dưới đây là một ví dụ:

java Copy
@Test
public void testTodoRepositoryByCode() {
    todoRepository.save(new Todo(0, "Todo-1", "Detail-1"));
    todoRepository.save(new Todo(0, "Todo-2", "Detail-2"));

    Assertions.assertThat(todoRepository.findAll()).hasSize(2);
    Assertions.assertThat(todoRepository.findById(1).getTitle()).isEqualTo("Todo-1");
}

Trong ví dụ này, chúng ta đã thêm hai bản ghi Todo bằng cách sử dụng todoRepository, sau đó kiểm tra xem chúng đã được thêm thành công hay không.

Sử dụng @Sql

Một cách tốt hơn để chuẩn bị dữ liệu cho các test case là sử dụng annotation @Sql. Annotation này cho phép bạn chạy các tệp script SQL trước khi thực hiện các test case. Dưới đây là một ví dụ:

createTodo.sql

sql Copy
INSERT INTO todo (title, detail) VALUES ('Todo-1', 'Do homework');
INSERT INTO todo (title, detail) VALUES ('Todo-2', 'Walking');

Để chạy script SQL này trong test case, bạn có thể sử dụng annotation @Sql như sau:

java Copy
@RunWith(SpringRunner.class)
@DataJpaTest
public class SqlAnnotationTest {
    @Autowired
    private TodoRepository todoRepository;

    @Test
    @Sql("/createTodo.sql")
    public void testTodoRepositoryBySqlSchema() {
        Assertions.assertThat(todoRepository.findAll()).hasSize(2);
        Assertions.assertThat(todoRepository.findById(1).getTitle()).isEqualTo("Todo-1");
    }
}

Annotation @Sql giúp bạn thực thi các tệp script SQL trước khi thực hiện các test case. Điều này giúp bạn chuẩn bị dữ liệu một cách dễ dàng và nhanh chóng.

Tóm tắt

Trong bài viết này, chúng ta đã tìm hiểu cách thực hiện testing trong Spring Boot bằng cách sử dụng các annotation như @DataJpaTest@Sql. Testing là một phần quan trọng của quá trình phát triển ứng dụng để đảm bảo tính ổn định và đúng đắn của mã nguồn. Chúng ta cũng đã thấy cách chuẩn bị dữ liệu cho các test case một cách hiệu quả.

Avatar
Được viết bởi

Admin Team

Gợi ý câu hỏi phỏng vấn

Không có dữ liệu

Không có dữ liệu

Gợi ý bài viết
Không có dữ liệu

Không có dữ liệu

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào