java - @MockBean 似乎重新运行上下文创建并在 Migrate.sql 之后失败
问题描述
我有两个集成测试类。其中一个类依赖于与外部服务对话的 bean,所以我需要模拟这个 bean,并且@MockBean
看起来非常适合这个。为了将一些种子注入数据库,我使用flyway
的是afterMigrate.sql
. 所以这里很热,它看起来像:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest
@Transactional
@Rollback
class FooTest {
@Autowired
private MyService myService;
}
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest
@Transactional
@Rollback
class BarTest {
@MockBean
private ExternalService;
@Autowired
private MyService myService;
}
并且afterMigrate.sql
:
INSERT INTO my_table (id, name) VALUES (1, 'John Doe')
当我注释 as now 运行两次并且我收到错误时,问题ExternatService
出现@MockBean
了afretMigrate.sql
:
java.lang.IllegalStateException: Failed to load ApplicationContext
....
Message : ERROR: duplicate key value violates unique constraint "my_table_pkey"
当我更改为时@MockBean
,@Autowired
错误消失了,并且创建了上下文没有任何问题。BarTest
此外,如果我单独运行,测试运行没有问题。@MockBean
正如文档所说,这不是预期的行为:
在上下文中定义的任何现有的相同类型的单个 bean 都将被模拟替换。如果没有定义现有的 bean,将添加一个新的。将不会找到应用程序上下文已知但不是 bean 的依赖项(例如直接注册的那些),并且模拟 bean 将与现有依赖项一起添加到上下文中。
它并没有说将重新创建上下文。
解决方案
因为当您使用@MockBean
注释时,将为每个测试加载您的上下文。请参考这个 github 问题。此页面的引文:
Spring 测试框架将在测试运行之间尽可能缓存一个 ApplicationContext。为了被缓存,上下文必须具有完全相同的配置。每当您使用@MockBean 时,根据定义,您都在更改上下文配置。
因此,当您在不同的测试中使用模拟 bean 时 - 每次都会为您的测试类重新创建上下文。因此,例如,如果您有一些在创建上下文时将数据加载到 DB 的 bean——例如用于 flyway 的 bean——它们将在每次重新创建上下文时创建。
推荐阅读
- flutter - scrollController.animateTo 异步调用多次
- javascript - 在卡片中垂直对齐文本(Vuetify)
- zsh - 为什么 zsh 的插件 z 在 .zshrc 中不活动?
- angular - 查找最大 div 元素的高度并为所有 div 元素设置它 Angular 8
- reactjs - React Hooks-forEach 数组不起作用
- r - GGplot饼图错误:美学必须是长度1或与数据相同(98):y
- gnu-make - 如何编译比特币核心使其更便携?
- python - 创建数据框的嵌套字典时,如何根据数据框的列表名称命名字典?
- python - 我无法登录到我的 Django 用户凭据
- heroku - API Rest 与 Hyperledger Fabric 和节点 js Heroku