0Pricing
Testing Mastery: JUnit, Mockito & Integration Tests · 课时

测试 RESTful API

使用 `MockMvc` 或 `WebTestClient` 为 Spring Boot REST 控制器编写全面的集成测试。

测试 RESTful API 是 CoddyKit 上的免费 Testing Mastery: JUnit, Mockito & Integration Tests 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Testing Mastery: JUnit, Mockito & Integration Tests 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Testing Mastery: JUnit, Mockito & Integration Tests 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Why Test REST APIs?

RESTful APIs are the backbone of many modern applications. Testing them is crucial to ensure they work as expected, handle various inputs, and return correct responses.

This lesson focuses on how to write integration tests for your Spring Boot REST controllers using powerful tools: MockMvc and WebTestClient.

Spring Boot Test Setup

To test Spring Boot controllers, we need a special setup. The @SpringBootTest annotation loads the full application context, and @AutoConfigureMockMvc configures MockMvc for us.

Here's a basic structure for a controller test class:

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.test.web.servlet.MockMvc;

@SpringBootTest
@AutoConfigureMockMvc
public class MyApiControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void contextLoads() {
        // Your tests will go here
    }
}

Introducing MockMvc

MockMvc allows you to test your Spring MVC controllers without starting a full HTTP server. It simulates HTTP requests and responses, making tests fast and isolated.

It's ideal for testing the controller layer, ensuring routes, request mappings, and response formats are correct.

MockMvc: Testing GET Requests

Let's test a simple GET endpoint, for example, /api/hello which returns "Hello, CoddyKit!". We'll verify the HTTP status code and the response content.

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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

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;

// Assume a @RestController with @GetMapping("/api/hello") returning "Hello, CoddyKit!"
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testHelloEndpoint() throws Exception {
        mockMvc.perform(get("/api/hello"))
               .andExpect(status().isOk())
               .andExpect(content().string("Hello, CoddyKit!"));
    }
}

MockMvc: GET with Path Variables

APIs often use path variables to identify resources, like /api/users/{id}. MockMvc handles these naturally.

Here's how to test an endpoint that takes an ID:

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.test.web.servlet.MockMvc;

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;

// Assume @GetMapping("/api/users/{id}") returns "User: " + id
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetUserById() throws Exception {
        mockMvc.perform(get("/api/users/{id}", 123))
               .andExpect(status().isOk())
               .andExpect(content().string("User: 123"));
    }
}

MockMvc: Testing POST Requests

For POST requests, you typically send a request body, often in JSON format. We can specify the content type and body using MockMvc.

Let's test an endpoint that creates an item:

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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

// Assume @PostMapping("/api/items") creates an item and returns it
@SpringBootTest
@AutoConfigureMockMvc
public class ItemControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testCreateItem() throws Exception {
        String newItemJson = "{\"name\":\"Laptop\", \"price\":1200}";
        mockMvc.perform(post("/api/items")
                       .contentType(MediaType.APPLICATION_JSON)
                       .content(newItemJson))
               .andExpect(status().isCreated())
               .andExpect(jsonPath("$.name").value("Laptop"));
    }
}

Introducing WebTestClient

WebTestClient is a non-blocking, reactive client for testing web applications. It's part of Spring WebFlux but can also be used to test Spring MVC controllers.

  • It can perform actual HTTP calls (if configured to hit a running server).
  • It can also be backed by MockMvc for server-side testing similar to MockMvc itself, but with a reactive API.

WebTestClient in Action

Using WebTestClient is similar to MockMvc, but its fluent API often feels more modern, especially for reactive applications. Let's re-test our /api/hello endpoint.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.web.reactive.server.WebTestClient;

// For WebTestClient with Spring MVC, we can use @SpringBootTest
// and inject WebTestClient.Builder to build it with MockMvc.webAppContextSetup
// For simplicity, this example assumes a WebFlux app or WebTestClient set up for MockMvc
// @SpringBootTest
// class HelloWebClientTest {
// @Autowired WebApplicationContext wac;
// WebTestClient client;
// @BeforeEach void setup() { client = WebTestClient.bindToApplicationContext(wac).build(); }
// ...

// For a simpler runnable example focusing on WebTestClient usage:
@WebFluxTest // This annotation sets up a minimal reactive context for WebTestClient
public class HelloWebClientTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void testHelloEndpoint() {
        webTestClient.get().uri("/api/hello")
                     .exchange()
                     .expectStatus().isOk()
                     .expectBody(String.class).isEqualTo("Hello, CoddyKit!");
    }
}

MockMvc vs. WebTestClient

When should you use MockMvc versus WebTestClient?

  • MockMvc: Best for traditional Spring MVC applications. It's server-side, simulates requests, and doesn't require a running server, making it fast.
  • WebTestClient: Ideal for reactive Spring WebFlux applications. It also provides a reactive client API for testing Spring MVC apps, offering a more modern, fluent way to write tests, and can even hit a live server for true end-to-end integration tests.

For most Spring Boot REST API integration tests focusing on the controller layer, MockMvc is a solid choice due to its speed and direct integration.

Quick Check: API Testing Tools

You are building a Spring Boot application using traditional Spring MVC. You want to write fast, isolated integration tests for your REST controllers without starting a full HTTP server.

Recap & Next Steps

In this lesson, you learned how to write comprehensive integration tests for your Spring Boot REST controllers. We covered:

  • Setting up your test environment with @SpringBootTest and @AutoConfigureMockMvc.
  • Using MockMvc to simulate GET and POST requests, verifying status and content.
  • Introducing WebTestClient for reactive testing and its alternative use cases.
  • Understanding the differences and when to choose between MockMvc and WebTestClient.

These tools are essential for building robust and reliable RESTful APIs!

常见问题解答

「测试 RESTful API」课时是免费的吗?

是的 — 「测试 RESTful API」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Testing Mastery: JUnit, Mockito & Integration Tests 课程的其余内容,请升级到 CoddyKit PRO。 Testing Mastery: JUnit, Mockito & Integration Tests 课程共包含 4 节课。

「测试 RESTful API」这节课中我会学到什么?

使用 `MockMvc` 或 `WebTestClient` 为 Spring Boot REST 控制器编写全面的集成测试。 你通过在浏览器中直接运行的动手代码来练习 Testing Mastery: JUnit, Mockito & Integration Tests,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Testing Mastery: JUnit, Mockito & Integration Tests 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Testing Mastery: JUnit, Mockito & Integration Tests 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「测试 RESTful API」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Testing Mastery: JUnit, Mockito & Integration Tests 课中编写并运行代码吗?

能。每节 Testing Mastery: JUnit, Mockito & Integration Tests 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Spring 测试上下文框架
  2. 测试 RESTful API
  3. 用于测试的嵌入式数据库
  4. 使用 @WebMvcTest 与 MockMvc 测试 Web 层
← 返回 Testing Mastery: JUnit, Mockito & Integration Tests