Java 编辑并重新运行spring引导单元测试,而无需重新加载上下文以加快测试速度
我有一个SpringBoot应用程序,并使用postgres测试容器()和JUnit编写了单元测试。测试具有@SpringBootTest注释,该注释在运行测试之前加载上下文并启动测试容器 在我比较旧的Macbook上加载上下文和启动容器大约需要15秒,但是测试本身非常快(每个都<100毫秒)。因此,在一个包含100个测试的完整构建中,这并不重要。这是15秒的一次性成本。 但是在IDE中单独开发/调试测试变得非常缓慢。每次测试都会产生15秒的启动成本Java 编辑并重新运行spring引导单元测试,而无需重新加载上下文以加快测试速度,java,spring-boot,unit-testing,junit,Java,Spring Boot,Unit Testing,Junit,我有一个SpringBoot应用程序,并使用postgres测试容器()和JUnit编写了单元测试。测试具有@SpringBootTest注释,该注释在运行测试之前加载上下文并启动测试容器 在我比较旧的Macbook上加载上下文和启动容器大约需要15秒,但是测试本身非常快(每个都
我知道IntelliJ和Springboot支持在应用程序运行时热重新加载类。对于单元测试,是否有类似的解决方案/建议?i、 e保持上下文加载和testcontainer(DB)运行,但只重新编译修改后的测试类并再次运行选定的测试。我无法想象测试中会出现热重新加载的神奇标志-有太多的东西会弄脏spring上下文、弄脏数据库等 在我看来,这里最容易做的事情是用manual container start本地替换测试容器初始值设定项,并更改数据库的属性以指向该容器。如果您希望实现自动化,您可以添加启动前脚本(如果您使用IntelliJ…)来执行类似操作:
docker start postgres | | docker run postgres
(linux),如果容器未运行,它将启动容器,如果容器正在运行,则不执行任何操作
通常IDE重新编译只是更改受影响的类,如果没有容器启动,Spring上下文可能不会启动15秒,除非您还有很多bean要配置…我正在尝试学习使用Spring Boot进行测试,如果这个答案不相关,那么很抱歉 我发现这表明了(按使用最多到最少的顺序)的组合:
- Mockito使用@Mock注释进行单元测试,如果可能的话,不使用Spring上下文
- 当您想要涉及一些Spring上下文时,使用@WebMvcTest注释对测试进行切片
- 当您希望涉及整个Spring上下文时,使用@SpringBootTest注释进行集成测试
import org.testcontainers.containers.BindMode;
导入org.testcontainers.containers.OracleContainer;
公共类StaticOracleContainer{
公共静态OracleContainer getContainer(){
返回LazyOracleContainer.ORACLE_CONTAINER;
}
私有静态类LazyOracleContainer{
私有静态最终OracleContainer ORACLE_CONTAINER=makeContainer();
私有静态OracleContainer makeContainer(){
最终OracleContainer=新OracleContainer()
//testcontainers将使用的用户名
//了解容器是否已启动并正在运行
.withUsername(“系统”)
//testcontainers将要使用的密码
//了解容器是否已启动并正在运行
.withPassword(“123”)
//告诉testcontainers,这些端口应该
//将映射到外部端口
.带有暴露端口(15215500)
//Oracle数据库将不会启动,如果
//超过1gb的共享内存可用,因此这是必要的
.带有共享内存大小(2147483648L)
//这与给出容器相同
//-v/path/to/init_db.sql:/u01/app/oracle/scripts/startup/init_db.sql
//容器启动后,Oracle将执行init_db.sql
.withClasspathResourceMapping(“init_db.sql”
,“/u01/app/oracle/scripts/startup/init_db.sql”
,BindMode.只读)
//不要破坏容器
.withReuse(真)
;
container.start();
返回容器;
}
}
}
正如你所看到的,这是一个单身汉。我需要它来手动控制testcontainers生命周期,这样我就可以使用可重用容器了
如果您想知道如何使用此单例将Oracle添加到Spring测试上下文中,可以看看我使用testcontainers的示例
不过,这种方法有一个问题。Testcontainers永远不会停止可重用容器。您必须手动停止并销毁容器。我相信有一个简单的解决方案可以解决您的问题。您尚未指定如何在测试中运行测试容器,但我有以下方法的成功经验: 对于在本地运行的测试,在笔记本电脑上启动一次postgres服务器(比如在工作日开始时)。它可以是停靠进程,甚至是常规postgresql安装 在测试期间,spring引导应用程序并不真正知道它与测试容器交互——它获取主机/端口/凭据,就这样——它使用这些参数创建了一个数据源 因此,对于本地开发,您可以修改与测试的集成
@Configuration
@ConditionalOnProperty(name = "test.local.mode", havingValue = "true", matchIfMissing = false)
public class MyDbConfig {
@Bean
public DataSource dataSource () {
// create a data source initialized with local credentials
}
}
spring:
main:
lazy-initialization: true