简体   繁体   English

Spring 为每个单元测试文件加载上下文

[英]Spring loads context for each unit test file

I have 16 Unit test case files.我有 16 个单元测试用例文件。 Each in this format:每个格式如下:

@SpringBootTest
class UserServiceTest {

  @Autowired
  UserService userService;

  @MockBean
  SomeDependency someDependency;

  @Test
  ...and so on

}

Whenever I run mvn clean install , it seems that spring is restarting/loading context 16 times.每当我运行mvn clean install ,spring 似乎都在重新启动/加载上下文 16 次。 I see these logs 16 times:我看到这些日志 16 次:

[INFO] Running com.base.UserServiceTest
2021-07-16 04:35:39.421 [INFO ] [main] o.s.t.c.s.AbstractTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.base.UserServiceTest], using SpringBootContextLoader
2021-07-16 04:35:39.423 [INFO ] [main] o.s.t.c.s.AbstractContextLoader - Could not detect default resource locations for test class [com.base.UserServiceTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2021-07-16 04:35:39.424 [INFO ] [main] o.s.t.c.s.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.base.UserServiceTest]: UserServiceTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2021-07-16 04:35:39.473 [INFO ] [main] o.s.b.t.c.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration com.base.Application for test class com.base.UserServiceTest
2021-07-16 04:35:39.475 [INFO ] [main] o.s.t.c.s.AbstractTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
2021-07-16 04:35:39.476 [INFO ] [main] o.s.t.c.s.AbstractTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4dc599a7, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@635f2d9b, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@7e83380f, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@6000fc20, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@1e95926, org.springframework.test.context.support.DirtiesContextTestExecutionListener@1bc08f75, org.springframework.test.context.transaction.TransactionalTestExecutionListener@7ce49f42, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@1b629d02, org.springframework.test.context.event.EventPublishingTestExecutionListener@5089c721, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@4fad5162, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@176bd95a, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@186edc38, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@6c0b0db, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@2343c720, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@6aab6b1b]

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.0)

2021-07-16 04:35:39.520 [INFO ] [main] o.s.b.StartupInfoLogger - Starting UserServiceTest using Java 11.0.2 on 
2021-07-16 04:35:39.523 [INFO ] [main] o.s.b.SpringApplication - The following profiles are active: local
2021-07-16 04:35:40.197 [INFO ] [main] o.s.m.w.MockServletContext - Initializing Spring TestDispatcherServlet ''
2021-07-16 04:35:40.197 [INFO ] [main] o.s.w.s.FrameworkServlet - Initializing Servlet ''
2021-07-16 04:35:40.199 [INFO ] [main] o.s.w.s.FrameworkServlet - Completed initialization in 1 ms
2021-07-16 04:35:40.211 [INFO ] [main] o.s.b.StartupInfoLogger - Started UserServiceTest in 0.732 seconds (JVM running for 9.613)
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.918 s - in com.base.UserServiceTest

This causes 2 problems:这会导致两个问题:

  1. There are a lot more tests to be added.还有很多测试要添加。 Even with 16 test files, it takes around 20 seconds to execute.即使有 16 个测试文件,执行也需要大约 20 秒。 So the process is slow.所以这个过程很慢。
  2. My application uses JPA to connect with DB, and during mvn clean install , although the application builds successfully, it gives this error in logs random number of times:我的应用程序使用 JPA 连接数据库,并且在mvn clean install期间,虽然应用程序构建成功,但它在日志中随机出现此错误:

2021-07-16 04:35:52.741 [ERROR] [main] czhpHikariPool - HikariPool-11 - Exception during pool initialization. org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections

I wonder if this context reloading is causing this as I perform mvn clean install often and that there might be a connection leak somewhere.我想知道这种上下文重新加载是否会导致这种情况,因为我经常执行mvn clean install并且某处可能存在连接泄漏。

Using JUnit 5/Jupiter and Spring 5.使用 JUnit 5/Jupiter 和 Spring 5。

Any help in fixing above 2 points is appreciated.任何帮助解决以上 2 点的问题表示赞赏。 Thanks.谢谢。

Spring Test caches your TestContext and re-uses it for another test if the context configuration fits.如果上下文配置合适,Spring Test 会缓存您的 TestContext并将其重新用于另一个测试。

However, if all your tests have a different setup (eg, the first test wants a mocked version of class A and the second test wants a mocked version of class B), caching won't help and Spring has to start a new context.但是,如果您所有的测试都有不同的设置(例如,第一个测试需要类 A 的模拟版本,而第二个测试需要类 B 的模拟版本),缓存将无济于事,Spring 必须启动一个新的上下文。

If you streamline the context setup for all your tests, Spring will reuse it and hence make the test execution fast.如果您简化所有测试的上下文设置,Spring 将重用它,从而加快测试执行速度。

In addition, the test you added (using @SpringBootTest ) is not a unit test (well - it always depends on the definition) as it starts the entire Spring context.此外,您添加的测试(使用@SpringBootTest不是单元测试(好吧 - 它始终取决于定义),因为它启动了整个 Spring 上下文。

If your plan is to write unit tests for your business logic, rather use just JUnit 5 and Mockito.如果您的计划是为您的业务逻辑编写单元测试,请只使用 JUnit 5 和 Mockito。 These tests are fast and there's no Spring support and hence no context started.这些测试很快,并且没有 Spring 支持,因此没有启动上下文。

For a broad overview of unit, integration, and end-to-end testing strategies for Spring Boot applications, take a look at this article .有关 Spring Boot 应用程序的单元、集成和端到端测试策略的广泛概述,请查看本文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM