java - 配置覆盖默认应用程序上下文 bean 的 Spring 的 @DataJpaTest
问题描述
我正在为我的@DataJpaTest 配置而苦苦挣扎。我想利用@DataJpaTest 提供的自动配置的spring 上下文,但我想覆盖它的一些bean。
这是我的主要课程:
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(BookInputPort bookInputPort) {
return args -> {
bookInputPort.addNewBook(new BookDto("ABC", "DEF"));
bookInputPort.addNewBook(new BookDto("GHI", "JKL"));
bookInputPort.addNewBook(new BookDto("MNO", "PRS"));
};
}
如您所见,我为 CommandLineRunner 提供了依赖于某些服务的实现。
我也有一个测试:
@DataJpaTest
public class BookRepositoryTest {
public static final String TITLE = "For whom the bell tolls";
public static final String AUTHOR = "Hemingway";
@Autowired
private BookRepository bookRepository;
@Test
public void testRepository() {
Book save = bookRepository.save(new Book(TITLE, AUTHOR));
assertEquals(TITLE, save.getTitle());
assertEquals(AUTHOR, save.getAuthor());
}
}
当我运行测试时,我收到以下错误:
No qualifying bean of type 'com.example.demo.domain.book.ports.BookInputPort' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
这很有意义!自动配置的测试只为上下文的“切片”提供实现。显然缺少 BookInputPort 的实现。我在测试上下文中不需要这个 commandLineRunner。我创建了一个不依赖于任何服务的 commandLineRunner。我可以尝试通过添加到我的测试类嵌套类来解决这个问题:
@TestConfiguration
static class BookRepositoryTestConfiguration {
@Bean
CommandLineRunner commandLineRunner() {
return args -> {
};
}
}
这样就解决了问题。有点儿。如果我有更多这样的测试,我将不得不将此嵌套类复制粘贴到每个测试类。这不是最佳解决方案。我试图将其外部化为可以由以下配置导入@Import
的配置:这是配置类:
@Configuration
public class MyTestConfiguration {
@Bean
public CommandLineRunner commandLineRunner() {
return args -> {
};
}
}
但随后应用程序失败并显示一条消息:
Invalid bean definition with name 'commandLineRunner' defined in com.example.demo.DemoApplication: Cannot register bean definition
在这种情况下,我检查了该错误和其他人在 SO 上的建议:
@DataJpaTest(properties = "spring.main.allow-bean-definition-overriding=true")
我这样做了,我得到了:
No qualifying bean of type 'com.example.demo.domain.book.ports.BookInputPort' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
这与我开始的问题完全相同。我采取了所有这些步骤,发现自己处于最初的位置。
你知道如何解决这个问题吗?我没有模糊的想法或线索。
解决方案
@DataJpaTest generally starts scanning from current package of the test class and scans upwards till it finds the class annotated with @SpringBootConfiguration.
So creating a SpringBootConfiguration class at the repository root package will create only beans defined within that package. On top of that we can add any customized test bean required for our test class in that configuration class.
@SpringBootConfiguration
@EnableAutoConfiguration
public class TestRepositoryConfig {
@Bean
public CommandLineRunner commandLineRunner() {
return args -> {
};
}
@Bean
public BookInputPort bootInputPort(){
return new BookInputPort();
}
}
推荐阅读
- javascript - 如何使用 React Native 创建一个 fadeIn 链动画
- android - 在 TensorFlow 中检测并获取位置
- java - 机器人按键无法在无头模式下工作
- react-native - 如何创建带断点的圆形滑块?
- python - 当我尝试导入 lxml.html 时出现导入错误
- python - 从 django ORM 检索查询
- java - 如何隐藏 s3 存储桶并从 Html 文件中访问密钥凭证
- r - 如何在R中将逻辑运算符设置为函数的参数
- ios - 在日期设置为 Jan 1, 1 时使用 iOS SDK DateFormatter 时的时间输出不符合预期
- c# - 是否需要拥有服务用户帐户才能将 ASP.NET Core 应用程序部署为 Windows 服务?