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

Spring for GraphQL集成测试配置:Repository接口实例化失败

解决Spring for GraphQL集成测试中无法加载Repository的问题

报错根源

@GraphQlTest属于切片测试,默认仅初始化GraphQL相关组件(控制器、GraphQL运行时等),不会自动配置Spring Data JPA的核心逻辑。你通过@Import直接导入AddressRepository接口,Spring无法实例化接口类——JPA Repository的实现类是Spring Data在运行时动态生成的代理对象,切片测试环境下不会触发这个生成流程,因此抛出实例化失败的错误。

解决方案

由于你需要访问Repository层和H2数据库完成测试,属于完整集成测试场景,推荐使用以下两种方案:

方案1:使用@SpringBootTest加载完整上下文(推荐)

该方案会加载整个Spring Boot应用上下文,自动处理JPA、数据库、Repository代理类生成等所有逻辑,配置更简洁。

修改后的测试类:

import com.soscarlos.dropit.entity.Address;
import com.soscarlos.dropit.repository.AddressRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.transaction.annotation.Transactional;

@SpringBootTest
@Transactional // 测试结束自动回滚数据,保证测试隔离
class AddressControllerTest {

    @Autowired
    GraphQlTester tester;

    @Autowired
    AddressRepository addressRepository;

    @BeforeEach
    void setUp() {
        // 测试前插入一条测试数据,确保断言有效
        Address testAddress = Address.builder()
                .street("Test Street")
                .city("Test City")
                .postCode(12345)
                .build();
        addressRepository.save(testAddress);
    }

    @Test
    void findAllAddresses() {
        // language=GraphQL
        String document = """
                query {
                    findAllAddresses {
                        id
                        street
                        city
                        postCode
                    }
                }
                """;

        tester.document(document)
                .execute()
                .path("findAllAddresses")
                .entityList(Address.class)
                .hasSize(1);
    }
}

关键说明:

  • @SpringBootTest:加载完整应用上下文,自动扫描并注入所有需要的Bean(包括Repository、Service)
  • @Transactional:避免测试数据污染数据库,每个测试方法执行后自动回滚操作
  • 移除@Import:完整上下文会自动处理Bean的依赖注入,无需手动导入

方案2:在切片测试中启用JPA支持(轻量测试场景)

如果只想测试GraphQL控制器逻辑,不想加载完整上下文,可以通过组合注解启用JPA测试配置:

import com.soscarlos.dropit.entity.Address;
import com.soscarlos.dropit.repository.AddressRepository;
import com.soscarlos.dropit.service.AddressService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.transaction.annotation.Transactional;

@GraphQlTest(AddressController.class)
@Import(AddressService.class) // 手动导入服务类,切片测试不会自动扫描
@DataJpaTest // 启用JPA测试配置,生成Repository代理类
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // 使用应用配置的H2数据库
@Transactional
class AddressControllerTest {

    @Autowired
    GraphQlTester tester;

    @Autowired
    AddressRepository addressRepository;

    @BeforeEach
    void setUp() {
        Address testAddress = Address.builder()
                .street("Test Street")
                .city("Test City")
                .postCode(12345)
                .build();
        addressRepository.save(testAddress);
    }

    @Test
    void findAllAddresses() {
        // language=GraphQL
        String document = """
                query {
                    findAllAddresses {
                        id
                        street
                        city
                        postCode
                    }
                }
                """;

        tester.document(document)
                .execute()
                .path("findAllAddresses")
                .entityList(Address.class)
                .hasSize(1);
    }
}

关键说明:

  • @DataJpaTest:触发Spring Data JPA的代理类生成逻辑,解决Repository接口无法实例化的问题
  • @AutoConfigureTestDatabase:指定使用应用中配置的H2内存数据库,而非默认嵌入式数据库

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:10:27