Spring 启动无法为服务测试自动装配存储库 bean class

Spring boot can not autowire repository bean for service test class

我正在为我的应用程序使用模拟存储库。
这是服务的外观片段:

@Service
public class WeatherStationService {

    @Autowired
    private WeatherStationRepositoryMock weatherRepository;

这是存储库代码:

@Repository
public class WeatherStationRepositoryMock {

    @Getter
    private List<WeatherStation> stations = new ArrayList<>(
            Arrays.asList(
                    new WeatherStation("huston", "Huston station", RandomGenerator.getRandomGeoInformation()),
                    new WeatherStation("colorado", "Colorado station", RandomGenerator.getRandomGeoInformation())
            )
    );

当我使用 @SpringBootApplication.

执行 main() 时它工作正常

然而,当我想运行测试时class:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MockConfig.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class WeatherStationServiceTest {

    @Autowired
    @Real
    private WeatherStationService weatherService;

失败并显示以下堆栈跟踪:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'edu.lelyak.repository.WeatherStationRepositoryMock' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

MockConfig内容如下:

@Configuration
public class MockConfig {
    //**************************** REAL BEANS ******************************
    @Bean
    @Real
    public WeatherStationService weatherServiceReal() {
        return  new WeatherStationService();
    }

Real是真实实例的标记注释:

@Retention(RUNTIME)
@Qualifier
public @interface Real {
}

我可以在服务的下一次初始化中修复它:

@Service
public class WeatherStationService {
    private WeatherStationRepositoryMock weatherRepository = new WeatherStationRepositoryMock();

它工作正常。

为什么会这样?
如何修复我的自定义存储库的自动装配 class?

@SpringBootApplication 隐式定义了 @ComponentScan,它会扫描所有子包中的 bean。 当您 运行 使用 MockConfig 进行测试时,它不会扫描 bean。

解决方案 - 使用 @ComponentScan 或在 MockConfig 中定义 bean

(1) 使用@ComponentScan:

@Configuration
@ComponentScan //Make sure MockConfig is below all beans to discover
public class MockConfig {
    @Bean
    @Real
    public WeatherStationService weatherServiceReal() {
        return  new WeatherStationService();
    }
}

(2) 或定义所需的 beans:

@Configuration
public class MockConfig {
    @Bean
    @Real
    public WeatherStationService weatherServiceReal() {
        return  new WeatherStationService();
    }

    @Bean
    public WeatherStationRepositoryMock weatherStationRepository() {
        return new WeatherStationRepositoryMock()
    }
}