You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用MockMvc为Spring Boot含if-else逻辑的代码编写测试用例

Hey there! Let's break down how to write comprehensive MockMvc tests that cover every single if-else branch in your CartService and CartController. We'll use Mockito to mock your repository dependencies so we can control their return values and trigger each code path intentionally.

First, a quick heads-up: Your CartController uses @GetMapping for /addToCart but accepts a @RequestBody—this isn't standard HTTP practice (GET requests shouldn't include a request body). I'd recommend switching this to @PostMapping instead, and our test cases will use POST requests to match that corrected setup.


Step 1: Set Up the Test Class

Create a test class with annotations to enable Spring MVC testing and mock all dependencies used by your service:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(CartController.class)
public class CartControllerTest {

    @Autowired
    private MockMvc mockMvc;

    // Mock all repository/service dependencies used by CartService
    @MockBean
    private LoginRepository loginRepository;

    @MockBean
    private ProductRepository productRepository;

    @MockBean
    private CartRepository cartRepository;

    @MockBean
    private EmailService emailService;

    // Helper to convert Cart objects to JSON for request bodies
    private String asJsonString(Object obj) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(obj);
    }
}

Step 2: Test Every Code Branch

We'll write a test case for each if-else path in your CartService.cart() method:

Branch 1: Invalid Login Credentials

Triggers the outermost else block (login fails), returning 404 Not Found.

@Test
void addToCart_InvalidLogin_ReturnsNotFound() throws Exception {
    // Arrange: Create a cart with invalid login details
    Cart invalidCart = new Cart("wrongUser", "wrongPass", "test@example.com", "Laptop", "999", "Great laptop");
    
    // Mock login repo to reject the credentials
    when(loginRepository.existsByUserNameAndPassword(eq("wrongUser"), eq("wrongPass")))
        .thenReturn(false);

    // Act & Assert
    mockMvc.perform(post("/addToCart")
            .contentType(MediaType.APPLICATION_JSON)
            .content(asJsonString(invalidCart)))
            .andExpect(status().isNotFound());
}

Branch 2: Valid Login But Null Product Name

Triggers the else block where productname == null, returning 400 Bad Request.

@Test
void addToCart_ValidLogin_NullProductName_ReturnsBadRequest() throws Exception {
    // Arrange: Cart with valid login but no product name
    Cart cartWithNullProduct = new Cart("validUser", "validPass", "test@example.com", null, "999", "Great laptop");
    
    // Mock login repo to accept the credentials
    when(loginRepository.existsByUserNameAndPassword(eq("validUser"), eq("validPass")))
        .thenReturn(true);

    // Act & Assert
    mockMvc.perform(post("/addToCart")
            .contentType(MediaType.APPLICATION_JSON)
            .content(asJsonString(cartWithNullProduct)))
            .andExpect(status().isBadRequest());
}

Branch 3: Valid Login & Product Name, But Product Doesn't Exist

Triggers the else block where the product isn't found in ProductRepository, returning 404 Not Found with a custom message.

@Test
void addToCart_ValidLogin_ProductNotFound_ReturnsNotFound() throws Exception {
    // Arrange: Cart with valid login and non-existent product details
    Cart cartWithMissingProduct = new Cart("validUser", "validPass", "test@example.com", "NonExistentLaptop", "999", "Great laptop");
    
    // Mock login repo to accept credentials
    when(loginRepository.existsByUserNameAndPassword(eq("validUser"), eq("validPass")))
        .thenReturn(true);
    
    // Mock product repo to report the product doesn't exist
    when(productRepository.existsByProductNameAndPriceAndDiscription(
            eq("NonExistentLaptop"), eq("999"), eq("Great laptop")))
        .thenReturn(false);

    // Act & Assert
    mockMvc.perform(post("/addToCart")
            .contentType(MediaType.APPLICATION_JSON)
            .content(asJsonString(cartWithMissingProduct)))
            .andExpect(status().isNotFound())
            .andExpect(jsonPath("$.message").value("entity not found"));
}

Branch 4: All Conditions Met (Happy Path)

Triggers all if blocks, successfully adding the product to the cart and returning a success message.

@Test
void addToCart_AllValid_ReturnsSuccess() throws Exception {
    // Arrange: Cart with valid login and existing product details
    Cart validCart = new Cart("validUser", "validPass", "test@example.com", "Laptop", "999", "Great laptop");
    
    // Mock login repo to accept credentials
    when(loginRepository.existsByUserNameAndPassword(eq("validUser"), eq("validPass")))
        .thenReturn(true);
    
    // Mock product repo to confirm the product exists
    when(productRepository.existsByProductNameAndPriceAndDiscription(
            eq("Laptop"), eq("999"), eq("Great laptop")))
        .thenReturn(true);
    
    // Mock cart repo to return a count of 1 (existing items in cart)
    when(cartRepository.countByUserName(eq("validUser")))
        .thenReturn(1);
    
    // Mock the save operation (we don't need to persist real data)
    doNothing().when(cartRepository).save(any(Cart.class));

    // Act & Assert
    mockMvc.perform(post("/addToCart")
            .contentType(MediaType.APPLICATION_JSON)
            .content(asJsonString(validCart)))
            .andExpect(status().isOk())
            .andExpect(content().string("{\"message\":\"product Successfully added to cart\"}"));
    
    // Optional: Verify the cart repo's save method was called exactly once
    verify(cartRepository, times(1)).save(any(Cart.class));
}

Key Notes

  • Mocking Logic: @MockBean replaces real repository beans with Mockito mocks, letting us control their return values to trigger specific code paths.
  • JSON Serialization: The asJsonString helper converts your Cart object to JSON—ensure your Cart class has a no-arg constructor and getters/setters for Jackson to work correctly.
  • Validation: If you add validation annotations to your Cart class (like @NotNull for required fields), you can add additional tests to verify invalid input returns 400 Bad Request.

内容的提问来源于stack exchange,提问作者user14563905

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:18:19