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

Spring Boot本地测试@PutMapping接口update方法数据传输问题

问题梳理
  • 远程PostgreSQL数据库权限报错:

org.postgresql.util.PSQLException: ERROR: permission denied for table TEST_Company

  • 业务问题:更新操作中仅SstRegistrationNo字段未同步到数据库,怀疑与toCompanyResponse方法有关,但不确定
  • 需求:本地测试数据传输的方法,以及单元测试实现方案

一、先解决远程数据库权限问题

这是接口测试的前提,需给数据库用户授予TEST_Company表的更新权限,执行PostgreSQL命令:

-- 授予更新权限
GRANT UPDATE ON TEST_Company TO 你的数据库用户名;

-- 若需要全表操作权限,可执行
GRANT ALL PRIVILEGES ON TEST_Company TO 你的数据库用户名;

二、排查SstRegistrationNo字段未同步问题

注意:toCompanyResponse仅负责将实体转为响应DTO,不影响数据库写入逻辑,数据库写入是在repository.save(companyEntityToBeUpdated)步骤完成的,建议从以下方向排查:

  • 检查Company类的sstRegistrationNo字段:是否有正确的JSON序列化/反序列化注解(如@JsonProperty),确保Postman传入的JSON字段名与实体类字段匹配(注意大小写、下划线命名差异)
  • 检查CompanyEntity类的sstRegistrationNo字段:是否通过@Column注解正确映射到数据库列(例如数据库列是sst_registration_no,实体类需对应配置)
  • 验证传入数据:在update方法中添加日志,打印company.getSstRegistrationNo()的值,确认请求是否正确传递了该字段

三、本地测试数据传输的方法

1. 使用H2内存数据库本地验证

添加H2依赖(pom.xml):

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

配置application-test.yml:

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driverClassName: org.h2.Driver
    username: sa
    password:
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
  h2:
    console:
      enabled: true

启动项目后,访问http://localhost:8080/h2-console即可查看内存数据库,测试接口时可直接验证数据是否正确写入。

2. 打印SQL语句验证执行逻辑

在application.yml中开启SQL日志,查看实际执行的UPDATE语句是否包含SstRegistrationNo字段:

spring:
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true

控制台会输出格式化后的SQL语句,可直接确认更新字段是否完整。

3. 本地断点调试

在repository.save()方法前添加断点,查看companyEntityToBeUpdated对象的sstRegistrationNo字段值,确认业务逻辑是否正确设置了该字段。


四、单元测试方案

1. 服务层单元测试(Mock Repository)

用Mockito模拟Repository,验证update方法的字段赋值逻辑:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
class CompanyServiceTest {

    @Mock
    private CompanyRepository repository;

    @Mock
    private SeedValueRepository seedValueRepository;

    @InjectMocks
    private CompanyService companyService;

    @Test
    void update_ShouldUpdateSstRegistrationNo() {
        // 测试数据准备
        Long companyId = 1L;
        Company request = new Company();
        request.setSstRegistrationNo("SST-2024-001");

        CompanyEntity existingEntity = new CompanyEntity();
        existingEntity.setId(companyId);
        existingEntity.setSstRegistrationNo("OLD-SST-001");

        // Mock Repository行为
        when(repository.findById(companyId)).thenReturn(java.util.Optional.of(existingEntity));
        when(repository.save(any(CompanyEntity.class))).thenReturn(existingEntity);

        // 执行测试方法
        companyService.update(companyId, request);

        // 验证字段更新
        assertEquals("SST-2024-001", existingEntity.getSstRegistrationNo());
        // 验证save方法被调用
        verify(repository, times(1)).save(existingEntity);
    }
}

2. 控制器层集成测试

用MockMvc测试接口请求的参数传递:

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.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(CompanyController.class)
class CompanyControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private CompanyService companyService;

    @Test
    void update_ShouldPassSstRegistrationNo() throws Exception {
        Long companyId = 1L;
        String requestJson = "{\"sstRegistrationNo\":\"SST-2024-001\"}";

        when(companyService.update(eq(companyId), any(Company.class))).thenReturn(new CompanyResponse());

        mockMvc.perform(put("/companies/{companyId}", companyId)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(requestJson))
                .andExpect(status().isOk());

        verify(companyService, times(1)).update(eq(companyId), any(Company.class));
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:46:04