java Spring Boot 测试:为每个测试加载上下文?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48929585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 10:13:00  来源:igfitidea点击:

Spring boot test: context loaded for every test?

javaspringspring-bootjunitspring-boot-test

提问by Perimosh

In my project we have a super class for all our tests. This is the signature of that class

在我的项目中,我们有一个用于所有测试的超类。这是那个班级的签名

@RunWith(SpringRunner.class)
@SpringBootTest(value = {"management.port=0"}, classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"localhost", "test"})
@ContextConfiguration(classes = {Application.class, SomeConfiguration.class})
@Ignore
public abstract class AIntegrationTest {

Where Application.class is our main class, and SomeConfiguration.class it just for some @Bean and other stuff, nothing fancy.

其中 Application.class 是我们的主类,而 SomeConfiguration.class 只是用于一些 @Bean 和其他东西,没什么特别的。

I use gradle, and for running my tests I do:

我使用 gradle,为了运行我的测试,我这样做:

./gradlew :my-project:test

My problems are:

我的问题是:

  • I'm not sure if for each test the context is being initialized. But I can assure the context gets initialized multiple times. I know this by looking at the logs.
  • Since multiple contexts are initialized, it seems that contexts overlap with each other. I know this because one of the symptoms is this exception:

    Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.cloud.context.environment.EnvironmentManager@36408d9e] with key 'environmentManager'; nested exception is javax.management.InstanceAlreadyExistsException: RedeemAway:name=environmentManager,type=EnvironmentManager
    
  • Even if I don't care about the multiple contexts being loaded, is my impression that when a test finishes, the next test gets a new context BEFORE the previous one is terminated. I said this because of the overlapping of the exception from above.

  • 我不确定每个测试的上下文是否正在初始化。但我可以保证上下文被初始化多次。我通过查看日志知道这一点。
  • 由于初始化了多个上下文,因此上下文似乎相互重叠。我知道这一点,因为其中一个症状就是这个例外:

    Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.cloud.context.environment.EnvironmentManager@36408d9e] with key 'environmentManager'; nested exception is javax.management.InstanceAlreadyExistsException: RedeemAway:name=environmentManager,type=EnvironmentManager
    
  • 即使我不关心加载的多个上下文,我的印象是,当一个测试完成时,下一个测试在前一个终止之前获得一个新的上下文。我这么说是因为上面的异常重叠了。

Since all the tests share the same JVM, when some beans get registered twice, that exception rises up. From this link:

由于所有测试共享同一个 JVM,当某些 bean 被注册两次时,该异常就会出现。从这个链接:

Context caching

上下文缓存

It is said that:

据说:

An ApplicationContext can be uniquely identified by the combination of configuration parameters that is used to load it. Consequently, the unique combination of configuration parameters is used to generate a key under which the context is cached. The TestContext framework uses the following configuration parameters to build the context cache key

ApplicationContext 可以通过用于加载它的配置参数的组合来唯一标识。因此,配置参数的唯一组合用于生成缓存上下文的密钥。TestContext 框架使用以下配置参数来构建上下文缓存键

I understand that, but, I'm wondering how can I achieve that? My goal is to run all my tests over the same JVM and reuse the context with every test.

我明白这一点,但是,我想知道我怎样才能做到这一点?我的目标是在同一个 JVM 上运行我的所有测试,并在每个测试中重用上下文。

EDIT on Thu Feb 22

2 月 22 日星期四编辑

Things I tried:

我尝试过的事情:

  • spring.jmx.enabled: false
  • spring.jmx.default-domain: some-value
  • spring.jmx.enabled: 假
  • spring.jmx.default-domain: 一些值

Really disabling JMX shouldn't help since the excpetion is around the EnvironmentManager, which is from Spring Cloud.

真正禁用 JMX 应该无济于事,因为 excpetion 围绕 EnvironmentManager,它来自 Spring Cloud。

采纳答案by Perimosh

I found the answer to my problem. Here is well explained:

我找到了我的问题的答案。这里很好解释:

https://github.com/spring-projects/spring-boot/issues/7174

https://github.com/spring-projects/spring-boot/issues/7174

Basically, if you run a bunch of tests, as soon as one of them gets started, if it uses the annotation @MockBean it will force Spring to reload the context.

基本上,如果你运行一堆测试,一旦其中一个开始,如果它使用注释@MockBean,它将强制 Spring 重新加载上下文。

Bonus: you will see the same behavior if your test uses org.mockito.Mock.

奖励:如果您的测试使用 org.mockito.Mock,您将看到相同的行为。