Springboot + Junit5 应用程序无法在 CI 运行器的单元测试中加载 ApplicationContext,但可以在本地工作

问题描述 投票:0回答:1

我编写了一个简单的测试来检查 springboot 应用程序上下文,它使用 android studio(在 Windows 上)在我的本地计算机上执行得非常好,并且测试通过了。当我设置断点并暂停执行时,我还可以看到数据被添加到数据库中。然而,当使用 github 操作在 CI 运行器中执行测试来验证拉取请求时,它无法加载应用程序上下文并给出以下错误:

java.lang.IllegalStateException:超过ApplicationContext失败阈值(1):跳过重复尝试加载[WebMergedContextConfiguration@7367f3ce testClass = proj.rpc.database.entities.InventoryEntityUnitTest,locations = [],classes = [proj.App]的上下文, contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate .observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f,org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0,org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@41bcbe97,org.springframework.boot.test .context.filter.ExcludeFilterContextCustomizer@bd9c61a,org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@23142e20,org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0,org.springframework.boot.test.web .client.TestRestTemplateContextCustomizer@cdd28d1,org.springframework.boot.test.context.SpringBootTestAnnotation@8daa8220],resourceBasePath =“src / main / webapp”,contextLoader = org.springframework.boot.test.context.SpringBootContextLoader,父= null] 在org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:145) 在 org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130) 在 org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191) 在org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130) 在 org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260) 在 org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163) 在 java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) 在 java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) 在 java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) 在 java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) 在 java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) 在 java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) 在 java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) 在 java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) 在 java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) 在 java.base/java.util.Optional.orElseGet(Optional.java:364) 在 java.base/java.util.ArrayList.forEach(ArrayList.java:1511) 在 java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

代码:

用于测试的application.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/testcopilot
    username: mak
    password: ${POSTGRES_USER_PASSWORD}
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect

应用程序.kt

package proj

import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean

@SpringBootApplication
class App {
    @Bean
    fun commandLineRunner(ctx: ApplicationContext): CommandLineRunner? {
        return CommandLineRunner {
            // do nothing
        }
    }
}

fun main(args: Array<String>) {
    runApplication<App>(*args)
}

用户实体.kt

package proj.rpc.database.entities

import com.fasterxml.jackson.annotation.JsonIgnore
import jakarta.persistence.CascadeType
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.OneToMany
import jakarta.persistence.Table
import java.time.LocalDate

@Entity
@Table(name = "users")
open class UserEntity : Persistable<Long> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    internal var id: Long? = null

    @Column(unique = true)
    private var email: String? = null

    internal constructor()

    constructor(
        email: String
    ) {
        this.email = email
    }

    override fun getId(): Long? {
        return id
    }

    override fun isNew(): Boolean {
        return id == null
    }

    open fun setEmail(email: String) {
        this.email = email
    }

    open fun getEmail(): String? {
        return email
    }
}

用户存储库.kt

package proj.rpc.database.repositories

import proj.rpc.database.entities.UserEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface UserRepository : JpaRepository<UserEntity, Int>

UserRepoUnitTest.kt

package proj.rpc.database.entities

import proj.rpc.database.repositories.UserRepository
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.ApplicationContext
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDate

@SpringBootTest
@Transactional
class UserRepoUnitTest {
    @Autowired
    private lateinit var userRepo: UserRepository

    @Test
    fun contextLoads(context: ApplicationContext?) {
        assertNotNull(context)
    }
}

我的本地设置

我正在使用 Android studio 通过基于 gradle 的项目设置来开发代码。

根据

javac --version

,操作系统是Windows 10,Java版本是17.0.9

我尝试通过https://github.com/nektos/act在本地执行github操作,以确保与CI管道相同的环境,并且问题也可以在本地重现。所以我的预感是我的 android studio 在设置/环境上与 CI 运行器有一些差异,我无法弄清楚。

编辑:为简洁起见更新了代码。

spring-boot kotlin hibernate junit5 java-17
1个回答
0
投票

我自己弄清楚了这个案例中的问题所在。发生这种情况是因为应用程序无法连接到主机上的数据库。我必须特别确保 Postgres 在使用 postgres 服务容器的主机上可用,如下所示https://docs.github.com/en/actions/using-containerized-services/creating-postgresql-service-containers

© www.soinside.com 2019 - 2024. All rights reserved.