配置 Spring 的 @DataJpaTest 以覆盖默认应用程序上下文 bean
Configuring Spring's @DataJpaTest that overrides default application context beans
我正在努力配置我的@DataJpaTest。我想利用@DataJpaTest 提供的自动配置的 spring 上下文,但我想覆盖其中的一些 bean。
这是我的主class:
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: {}
非常有道理!自动配置的测试仅为上下文的 'slice' 提供实现。显然缺少 BookInputPort 的实现。我在测试环境中不需要这个 commandLineRunner。我创建了一个不依赖于任何服务的 commandLineRunner。
我可以尝试通过添加到我的测试 class nested class :
来解决问题
@TestConfiguration
static class BookRepositoryTestConfiguration {
@Bean
CommandLineRunner commandLineRunner() {
return args -> {
};
}
}
问题解决了。有点儿。如果我有更多这样的测试,我将不得不将这个嵌套的 class 复制粘贴到每个测试 class。这不是最佳解决方案。
我试图将其外部化为可以由 @Import
导入的配置
这是配置 class:
@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
我检查了这个错误,其他人在这种情况下建议:
@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
仅加载 Spring 启动应用程序的 JPA 部分,应用程序上下文可能不会加载,因为您有 @DataJpaTest
注释。尝试用 @SpringBootTest
替换 @DataJpaTest
。
By default, tests annotated with @DataJpaTest
will use an embedded
in-memory database (replacing any explicit or usually auto-configured
DataSource). The @AutoConfigureTestDatabase
annotation can be used to
override these settings. If you are looking to load your full
application configuration, but use an embedded database, you should
consider @SpringBootTest
combined with @AutoConfigureTestDatabase
rather than this annotation.
在Spring启动测试中class你可以这样做
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class YourClassTest {
@Autowired
private YourService yourService;
它确实加载了所有服务,我使用它非常好
如何在一个环境而不是另一个环境中加载特定实体
- 您可以在实体中使用
@Profile
注释。
- 在 entities/services 上放置
@Profile({"prod"})
你不想加载测试 运行,并且
- 将
@Profile({"prod", "test"})
放在 entities/services 上,您希望在 test
和 prod
环境中加载
- 然后 运行
test
和 test
配置文件。它不会加载不必要的 entities
。
- 您也可以在其他服务上添加
@Profile
注释。
@DataJpaTest一般从测试的当前包class开始扫描,向上扫描,直到找到@SpringBootConfiguration注解的class。
因此在存储库根包中创建 SpringBootConfiguration class 将仅创建在该包中定义的 bean。最重要的是,我们可以在该配置 class.
中添加我们的测试 class 所需的任何自定义测试 bean
@SpringBootConfiguration
@EnableAutoConfiguration
public class TestRepositoryConfig {
@Bean
public CommandLineRunner commandLineRunner() {
return args -> {
};
}
@Bean
public BookInputPort bootInputPort(){
return new BookInputPort();
}
}
我正在努力配置我的@DataJpaTest。我想利用@DataJpaTest 提供的自动配置的 spring 上下文,但我想覆盖其中的一些 bean。
这是我的主class:
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: {}
非常有道理!自动配置的测试仅为上下文的 'slice' 提供实现。显然缺少 BookInputPort 的实现。我在测试环境中不需要这个 commandLineRunner。我创建了一个不依赖于任何服务的 commandLineRunner。 我可以尝试通过添加到我的测试 class nested class :
来解决问题@TestConfiguration
static class BookRepositoryTestConfiguration {
@Bean
CommandLineRunner commandLineRunner() {
return args -> {
};
}
}
问题解决了。有点儿。如果我有更多这样的测试,我将不得不将这个嵌套的 class 复制粘贴到每个测试 class。这不是最佳解决方案。
我试图将其外部化为可以由 @Import
导入的配置
这是配置 class:
@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
我检查了这个错误,其他人在这种情况下建议:
@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
仅加载 Spring 启动应用程序的 JPA 部分,应用程序上下文可能不会加载,因为您有 @DataJpaTest
注释。尝试用 @SpringBootTest
替换 @DataJpaTest
。
By default, tests annotated with
@DataJpaTest
will use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource). The@AutoConfigureTestDatabase
annotation can be used to override these settings. If you are looking to load your full application configuration, but use an embedded database, you should consider@SpringBootTest
combined with@AutoConfigureTestDatabase
rather than this annotation.
在Spring启动测试中class你可以这样做
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class YourClassTest {
@Autowired
private YourService yourService;
它确实加载了所有服务,我使用它非常好
如何在一个环境而不是另一个环境中加载特定实体
- 您可以在实体中使用
@Profile
注释。 - 在 entities/services 上放置
@Profile({"prod"})
你不想加载测试 运行,并且 - 将
@Profile({"prod", "test"})
放在 entities/services 上,您希望在test
和prod
环境中加载 - 然后 运行
test
和test
配置文件。它不会加载不必要的entities
。 - 您也可以在其他服务上添加
@Profile
注释。
@DataJpaTest一般从测试的当前包class开始扫描,向上扫描,直到找到@SpringBootConfiguration注解的class。
因此在存储库根包中创建 SpringBootConfiguration class 将仅创建在该包中定义的 bean。最重要的是,我们可以在该配置 class.
@SpringBootConfiguration
@EnableAutoConfiguration
public class TestRepositoryConfig {
@Bean
public CommandLineRunner commandLineRunner() {
return args -> {
};
}
@Bean
public BookInputPort bootInputPort(){
return new BookInputPort();
}
}