Tổng quan

Đối với việc test này, thì spring đóng vai trò cung cấp các bean do nó quản lý và bind vào các trường trong lớp test của chúng ta. Vậy nên không phải với mọi test framework chúng ta đều có thể làm việc dễ dàng với spring nếu spring chưa hỗ trợ cho framework đó. Và hiện tại thì spring đang hỗ trợ tốt nhất cho JUnit.

Cài đặt

Để sử dụng được spring test, chúng ta sẽ cần thêm dependencies vào project, ví dụ với maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>${spring.boot.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>${spring.boot.version}</version>
    <scope>test</scope>
</dependency>

Ví dụ

Hãy giả sử rằng chúng ta có một lớp service thế này:

package com.example.spring_test.service;

import org.springframework.stereotype.Service;

@Service
public class HelloService {

    public String hello(String who) {
        return "Hello " + who + '!';
    }
}

Và một lớp controller thế này:

package com.example.spring_test.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.spring_test.service.HelloService;

import lombok.AllArgsConstructor;

@RestController
@AllArgsConstructor
public class HomeController {

    private final HelloService helloService;

    @GetMapping("/hello")
    public String hello(@RequestParam String who) {
        return helloService.hello(who);
    }
}

Và để test hàm hello của lớp HomeController chúng ta sẽ cần tạo ra lớp HomeControllerTest:

package com.example.spring_test.test;

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;

import com.example.spring_test.service.HelloService;

@SpringBootTest
@AutoConfigureMockMvc
public class HomeControllerTest {

    @MockBean
    private HelloService helloService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        // given
        final String who = "World";
        final String hello = "Hello World!";
        when(helloService.hello(who)).thenReturn(hello);

        // when
        // then
        mockMvc.perform(get("/hello?who=World"))
            .andExpect(status().isOk())
            .andExpect(content().string(hello));

        verify(helloService, times(1)).hello(who);
    }
}

Các field được đánh dấu bởi MockBean annotation sẽ được spring mockup các lớp được đánh dấu với MockMvc annotation sẽ được spring lấy từ spring context và inject vào trong lớp test của chúng ta, còn việc thực thi test sẽ được thực hiện bởi test framework, cụ thể ở đây là junit.