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

带Mock的MvcMock REST接口测试属于集成测试还是单元测试?

测试类型判定结论

针对你提出的「使用了Mock组件的MvcMock REST接口测试是否属于集成测试」的问题,首先给出明确结论:这类测试不属于集成测试,属于控制器层的单元测试/切片测试。

判定逻辑说明

我们通常对集成测试的核心定义是:测试过程中会加载真实的多层组件依赖、不Mock核心业务链路的实现,验证不同模块/层之间的协作是否符合预期。你提到的TestRestTemplate测试完全符合这个定义:

  • 启动完整的Spring容器上下文
  • 使用真实的服务层、持久层组件,配合TestContainers、Flyway加载真实的测试数据库环境
  • 没有对核心业务逻辑做Mock,完整验证从请求接入到数据库交互的全链路流程

对比你提供的带Mock的MvcMock测试:

  • 虽然使用了@SpringBootTest注解,但核心的业务依赖CreateProductService被@MockkBean替换成了Mock对象,真实的业务逻辑完全没有执行
  • 测试只验证了控制器层的参数解析、请求路由、返回值序列化这几个单独的能力,没有和下层业务组件做真实交互

两类测试的代码示例对比

带Mock的MvcMock测试示例

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
internal class CreateProductRestControllerMvcTest {

    @Autowired
    private lateinit var mockMvc: MockMvc

    @Autowired
    private lateinit var objectMapper: ObjectMapper

    @MockkBean
    private lateinit var createProductService: CreateProductService

    @ParameterizedTest
    @ArgumentsSource(ValidCreateProductRequests::class)
    internal fun `POST a new Product, GIVEN without any exception, THEN return Product id and status 201`(request: CreateProductRequest) {
        // Given
        every { createProductService.invoke(request.toCommand()) } returns ProductId(1L)

        // When, Then
        this.mockMvc.post(REST_PRODUCTS) {
            contentType = APPLICATION_JSON
            content = objectMapper.writeValueAsString(request)
        }
            .andExpect {
                status { isCreated() }
                content { json((objectMapper.writeValueAsString(1L))) }
            }
    }
}

TestRestTemplate集成测试示例

@SpringBootTest(webEnvironment = RANDOM_PORT, classes = [Application::class])
@ActiveProfiles("test")
@Testcontainers
@FlywayTest
@ExtendWith(FlywayTestExtension::class)
class CreateProductRestControllerIntegrationTest {

    @Autowired
    private lateinit var restTemplate: TestRestTemplate

    private lateinit var headers: HttpHeaders

    @BeforeEach
    internal fun setUp() {
        headers = HttpHeaders()
        headers.contentType = MediaType.APPLICATION_JSON
    }


    @FlywayTest
    @ParameterizedTest
    @ArgumentsSource(ValidJsonRequestBodies::class)
    internal fun `POST new Product, GIVEN valid request, THEN returns 201`(json: String) {
        // Given
        val request: HttpEntity<String> = HttpEntity(json, headers)

        // When
        val result = restTemplate.postForEntity(REST_PRODUCTS, request, String::class.java);

        // Then
        assertNotNull(result.body)
        assertEquals(HttpStatus.CREATED, result.statusCode)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:24:02