Luc*_*ues 2 gradle kotlin spring-boot junit5 spring-kafka
我有一个使用 Spring Boot、Gradle 和 Kotlin 构建的应用程序,它与 Kafka 和 PostgreSQL 连接。我正在使用它resources/application.yml
作为配置文件。\n我想为每种测试创建一个特定的包:单元、集成和端到端,但现在我有一个仅用于单元测试的包。做这个的最好方式是什么?我正在使用 Junit5。
我想要这样的东西:
\napplication/\n\xe2\x94\x9c\xe2\x94\x80 src/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 e2e/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 integration/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 main/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 test/\nbuild.gradle.kts\ngradlew\ngradlew.properties\nsettings.gradle.kts\n
Run Code Online (Sandbox Code Playgroud)\n另外,我希望在运行单元测试时我的应用程序不要连接到 Kafka 或 Postgres,但在运行集成测试时我希望它这样做。我怎样才能做到这一点?
\n我尝试了 Kafka 的配置,但没有成功:
\napplication/\n\xe2\x94\x9c\xe2\x94\x80 src/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 e2e/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 integration/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 main/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 test/\nbuild.gradle.kts\ngradlew\ngradlew.properties\nsettings.gradle.kts\n
Run Code Online (Sandbox Code Playgroud)\n我还创建了一个注释来模拟所有 Kafka 消费者和生产者(这有效,但我不想在每个测试类中添加此注释)
\nspring\n autoconfigure:\n exclude: org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration\n
Run Code Online (Sandbox Code Playgroud)\n我的消费者看起来像这样:
\n@MockBeans(MockBean(MyConsumer::class), MockBean(MyProducer::class))\nannotation class MockKafka\n\n@SpringBootTest\n@MockKafka\nclass MyAwesomeTest { // tests here }\n
Run Code Online (Sandbox Code Playgroud)\n我的 application.yaml 文件如下所示:
\n@Component\nclass MyConsumer() {\n private val logger = LoggerFactory.getLogger(this.javaClass)\n\n @RetryableTopic(\n attempts = "\\${kafka-config.consumer.properties.retry.attempts}",\n backoff = Backoff(delayExpression = "\\${kafka-config.consumer.properties.retry.delay}"),\n fixedDelayTopicStrategy = FixedDelayStrategy.SINGLE_TOPIC\n )\n @KafkaListener(\n topics = ["\\${spring.kafka.topic.my-topic}"],\n groupId = "\\${spring.kafka.group-id}"\n )\n fun consumer(event: MyEvent) { // logic here }\n}\n
Run Code Online (Sandbox Code Playgroud)\nKotlin version: 1.5.0\nSpring Boot version: 2.4.6\nGradlew version: 7.0.2\n
Run Code Online (Sandbox Code Playgroud)\n提前致谢!
\n事实上,Gradle 在官方指南中确实描述了如何实现这一点。这是您的案例的示例build.gradle.kts
:
plugins {\n kotlin("jvm") version "1.5.0"\n\n id("org.springframework.boot") version "2.5.2"\n id("io.spring.dependency-management") version "1.0.11.RELEASE"\n}\n\ngroup = "com.example.app"\nversion = "0.1.0-SNAPSHOT"\n\nrepositories {\n mavenCentral()\n}\n\nsourceSets {\n create("intTest") {\n compileClasspath += sourceSets.main.get().output\n runtimeClasspath += sourceSets.main.get().output\n }\n create("e2eTest") {\n compileClasspath += sourceSets.main.get().output\n runtimeClasspath += sourceSets.main.get().output\n }\n}\n\nval intTestImplementation: Configuration by configurations.getting {\n extendsFrom(configurations.implementation.get())\n}\n\nval e2eTestImplementation: Configuration by configurations.getting {\n extendsFrom(configurations.implementation.get())\n}\n\nconfigurations["intTestImplementation"].extendsFrom(configurations.runtimeOnly.get())\nconfigurations["e2eTestImplementation"].extendsFrom(configurations.runtimeOnly.get())\n\ndependencies {\n implementation(platform("org.jetbrains.kotlin:kotlin-bom"))\n implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")\n implementation("org.springframework.boot:spring-boot-starter-web")\n\n testImplementation(platform("org.junit:junit-bom:5.7.2"))\n testImplementation("org.junit.jupiter:junit-jupiter")\n testImplementation("org.springframework.boot:spring-boot-starter-test")\n\n intTestImplementation(platform("org.junit:junit-bom:5.7.2"))\n intTestImplementation("org.junit.jupiter:junit-jupiter")\n intTestImplementation("org.springframework.boot:spring-boot-starter-test")\n\n e2eTestImplementation(platform("org.junit:junit-bom:5.7.2"))\n e2eTestImplementation("org.junit.jupiter:junit-jupiter")\n e2eTestImplementation("org.springframework.boot:spring-boot-starter-test")\n}\n\nval integrationTest = task<Test>("integrationTest") {\n description = "Runs integration tests."\n group = "verification"\n\n testClassesDirs = sourceSets["intTest"].output.classesDirs\n classpath = sourceSets["intTest"].runtimeClasspath\n shouldRunAfter("test")\n}\n\nval end2endTest = task<Test>("end2endTest") {\n description = "Runs end-to-end tests."\n group = "verification"\n\n testClassesDirs = sourceSets["e2eTest"].output.classesDirs\n classpath = sourceSets["e2eTest"].runtimeClasspath\n shouldRunAfter("test")\n}\n\ntasks.test {\n useJUnitPlatform()\n}\n\ntasks.getByName<Test>("integrationTest") {\n useJUnitPlatform()\n}\n\ntasks.getByName<Test>("end2endTest") {\n useJUnitPlatform()\n}\n\ntasks.check {\n dependsOn(integrationTest)\n dependsOn(end2endTest)\n}\n
Run Code Online (Sandbox Code Playgroud)\n现在文件夹结构可能是这样的:
\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 e2eTest\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app/controller\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 HelloControllerE2ETest.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 intTest\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app/controller\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 HelloControllerIntTest.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 controller/HelloController.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 App.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app/controller\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 HelloControllerTest.kt\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n
Run Code Online (Sandbox Code Playgroud)\n我不熟悉 Kafka,但在我自己的项目中,我对不同 PostgreSQL 设置的每个测试应用了不同的 Spring 配置文件。
\n首先,为每种测试分配配置文件build.gradle.kts
:
\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 e2eTest\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app/controller\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 HelloControllerE2ETest.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 intTest\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app/controller\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 HelloControllerIntTest.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 controller/HelloController.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 App.kt\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com/example/app/controller\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 HelloControllerTest.kt\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n
Run Code Online (Sandbox Code Playgroud)\n然后,创建特定于配置文件的应用程序配置文件到其相应的resources/config
:
\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 e2eTest\n \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources/config\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 application-e2e.yml\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 intTest\n \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources/config\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 application-integration.yml\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main\n \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources/config\n \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 application.yml\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 kotlin\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources/config\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 application-test.yml\n
Run Code Online (Sandbox Code Playgroud)\n应用程序将按以下方式加载配置:
\n命令 | 轮廓 | 配置加载顺序 |
---|---|---|
./gradlew bootRun | default | applicaiton.yml ( > application-default.yml ) |
./gradlew test | test | applicaiton.yml >application-test.yml |
./gradlew integrationTest | integration | applicaiton.yml >application-integration.yml |
./gradlew end2endTest | e2e | applicaiton.yml >application-e2e.yml |
现在您应该能够为每个测试配置不同的行为。
\n 归档时间: |
|
查看次数: |
1202 次 |
最近记录: |