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()
}
}
我正在为我的应用程序使用模拟存储库。
这是服务的外观片段:
@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
.
然而,当我想运行测试时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()
}
}