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

Spring Boot测试因缺失PopulatingService Bean启动失败求助

Spring Boot测试时找不到PopulatingService Bean的问题

问题概述

测试Spring REST API时,ApplicationContext加载失败,核心报错为:容器中不存在solita.citybike.services.PopulatingService类型的合格Bean。已在主类添加@EntityScan("solita.citybike"),怀疑与控制器注入两个Service有关,但无法定位具体原因。

错误栈

2023-05-10T22:45:38.615+03:00 ERROR 10504 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener] to prepare test instance [solita.citybike.JourneyControllerTest@77c1e611]

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@93824eb testClass = solita.citybike.JourneyControllerTest, locations = [], classes = [solita.citybike.controllers.JourneyController, solita.citybike.services.JourneyService, solita.citybike.repositories.JourneyRepository], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@792b749c, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@9da1, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@595a413a, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@87e31c, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@29d80d2b, [ImportsContextCustomizer@7af52ec7 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration, org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) ~[junit-rt.jar:na]
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) ~[junit-rt.jar:na]
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) ~[junit-rt.jar:na]
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'journeyController': Unsatisfied dependency expressed through field 'populatingService': No qualifying bean of type 'solita.citybike.services.PopulatingService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712) ~[spring-beans-6.0.6.jar:6.0.6]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692) ~[spring-beans-6.0.6.jar:6.0.6]
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:133) ~[spring-beans-6.0.6.jar:6.0.6]
org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137) ~[spring-boot-test-3.0.4.jar:3.0.4]
        at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59) ~[spring-core-6.0.6.jar:6.0.6]
        at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47) ~[spring-core-6.0.6.jar:6.0.6]
        at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1388) ~[spring-boot-3.0.4.jar:3.0.4]
        at 

    org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:545) ~[spring-boot-test-3.0.4.jar:3.0.4]
            at 
        Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'solita.citybike.services.PopulatingService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812) ~[spring-beans-6.0.6.jar:6.0.6]
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371) ~[spring-beans-6.0.6.jar:6.0.6]
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.6.jar:6.0.6]
            at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709) ~[spring-beans-6.0.6.jar:6.0.6]
            ... 98 common frames omitted
        
        
        java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@93824eb testClass = solita.citybike.JourneyControllerTest, locations = [], classes = [solita.citybike.controllers.JourneyController, solita.citybike.services.JourneyService, solita.citybike.repositories.JourneyRepository], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@792b749c, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@9da1, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@595a413a, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@87e31c, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@29d80d2b, [ImportsContextCustomizer@7af

52ec7 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@36804139, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@24959ca4, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@a4e0ef72, org.springframework.boot.test.context.SpringBootTestAnnotation@ce9cd5cb], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
        
            at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:142)
            at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
            at 
            ... 73 more
        Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'solita.citybike.services.PopulatingService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371)
            at 

org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709)
        ... 98 more
    
    
    Process finished with exit code -1

相关代码

主类代码

@SpringBootApplication
@EntityScan("solita.citybike")
public class JourneyBackend {

    public static void main(String [] args){
        SpringApplication.run(JourneyBackend.class, args);
    }
}

Controller代码

@RestController
@RequestMapping("journeys")
public class JourneyController {

    @Autowired
    public PopulatingService populatingService;

    @Autowired
    public JourneyService journeyService;

    @GetMapping
    public ResponseEntity<List<BikeJourney>> getAllJourneys(
            @RequestParam(defaultValue = "0") Integer pageNumber,
            @RequestParam(defaultValue = "15") Integer pageSize,
            @RequestParam(defaultValue = "id") String sortBy
    ){
        List<BikeJourney> journeyList = this.journeyService.getAllJourneys(pageNumber, pageSize, sortBy);


        return new ResponseEntity<List<BikeJourney>>(journeyList, new HttpHeaders(), HttpStatus.OK);


    }



   @GetMapping("/hello")
    public @ResponseBody String greeting() {
        return this.journeyService.test();
    }



    @PostMapping("/populate")
    public ResponseEntity<String> add(){



         if(this.populatingService.populateData()){
              return ResponseEntity.status(HttpStatus.OK).body("Data read from file to db succesfully");
       }

       return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Reading data from file failed");


 }

JourneyService代码

@Service
public class JourneyService {



    @Autowired
    private JourneyRepository journeyRepository;

    @Autowired
    private StationRepository stationRepository;



    public List<BikeJourney> getAllJourneys(Integer pageNumber, Integer pageSize, String sortBy) {

        Pageable paging = PageRequest.of(pageNumber, pageSize, Sort.by(sortBy));

        Page<BikeJourney> pagedResult = journeyRepository.findAll(paging);

        if(pagedResult.isEmpty()){
            return new ArrayList<>();
        }

        return pagedResult.getContent();

    }

    public String test() {
        return "cat";
    }


}

JourneyRepository代码

@Repository
public interface JourneyRepository extends PagingAndSortingRepository<BikeJourney, Integer> {



    List<BikeJourney> findAll();

    Iterable<BikeJourney> saveAll(Iterable<BikeJourney> validJourneys);

    Iterable<BikeJourney> deleteAll();
}

解决方案

核心原因

从错误栈的WebMergedContextConfiguration可以看出,测试上下文仅加载了JourneyController、JourneyService、JourneyRepository三类组件,但JourneyController依赖的PopulatingService不在加载列表中;同时需确认PopulatingService本身是否添加了Spring组件注解,否则容器不会将其注册为Bean。

修复步骤

  1. 为PopulatingService添加组件注解
    确保solita.citybike.services.PopulatingService类上添加@Service注解,示例:

    @Service
    public class PopulatingService {
        // 类实现逻辑
    }
    
  2. 调整测试类上下文配置

    • 若使用@WebMvcTest:该注解默认仅加载控制器相关Bean,需手动导入PopulatingService
      @WebMvcTest(JourneyController.class)
      @Import({JourneyService.class, PopulatingService.class})
      public class JourneyControllerTest {
          // 测试代码
      }
      
    • 若需完整上下文:改用@SpringBootTest替代@WebMvcTest,自动扫描所有组件(适合集成测试)
      @SpringBootTest
      @AutoConfigureMockMvc
      public class JourneyControllerTest {
          // 测试代码
      }
      
  3. 验证组件扫描范围
    @SpringBootApplication默认扫描主类所在包及其子包。若PopulatingService在solita.citybike.services包下,主类在solita.citybike包下,默认扫描范围已覆盖;若包结构不一致,需在主类添加@ComponentScan("solita.citybike.services")确保扫描到该类。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 14:18:07