gpt4 book ai didi

spring - 在 Spock 测试中加载 Spring 上下文*之前*如何启动嵌入式 Cassandra 服务器?

转载 作者:行者123 更新时间:2023-12-02 09:00:28 28 4
gpt4 key购买 nike

在我的一个集成测试中,我似乎遇到了一个棘手的排序问题。我有一个基于 Spring Boot/Spring MVC 和 Cassandra DB 的 REST 服务器。我使用 spring-data-cassandra jar 文件使 POJO 能够通过 CassandraTemplate 通过 CrudRepository 实现插入到数据库中。该应用程序工作正常,我可以进行 REST 调用,并且框架可以正确地将我的表单数据转换为 POJO 并将数据插入数据库中。到目前为止,一切都很好。

我想做的是编写一个执行整个堆栈的集成测试。显然,我不想依赖可用的外部数据库,因此我使用 cassandra-unit-spring 中的 EmbeddedCassandra 内容并通过 Spock 测试驱动它。我遇到的问题似乎与 @ContextConfiguration 注释中定义的 SpringApplicationContextLoader 和 @TestExecutionListener 注释中定义的 CassandraUnitTestExecutionListener 类之间的某种排序冲突有关。由于这是一个 Spock 测试,因此需要 SpringApplicationContextLoader 类来自动启动 Spring Boot 服务器。但是,它在 Cassandra 服务器启动之前执行此操作,这会导致 Cluster/Session beans 无法加载,因为它们显然会在创建后立即尝试联系服务器。我尝试了如此多的组合,让我头晕目眩。我不得不采取我认为非常丑陋的解决方案。我有一个 setup() 方法,它使用 bool 值来确保上下文和 Spring Boot 应用程序仅运行一次。我尝试将其放入 setupSpec() 方法中,该方法每个测试类仅运行一次,但这不起作用(一些 catch 22 问题)。如果我尝试 @Autowire 上下文,那么它会在 CassandraServer 启动之前被注入(inject)。正如我提到的,我尝试了无数不同的事情。

这个解决方案有效,但令我烦恼的是,我无法仅通过注释和 DI 使其以更优雅的方式工作。另外,@Value 注释的字段没有被初始化,这就是为什么我不得不在启动 Tomcat 后通过环境获取服务器端口的方法。非常欢迎任何有关如何“以正确的方式”做到这一点的建议。谢谢。

@ActiveProfiles(profiles = ["test"])
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = Application.class)
// @WebIntegrationTest("server.port:0") // Pick a random port for Tomcat
@EnableConfigurationProperties
@EmbeddedCassandra
@CassandraDataSet(value = ["cql/createUserMgmtKeySpace.cql", "cql/createUserMgmtTables.cql"], keyspace = "user_mgmt")
@TestExecutionListeners(listeners = [ CassandraUnitTestExecutionListener.class ]) //, DependencyInjectionTestExecutionListener.class ]) //, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
@Title("Integration test for the lineup ingestion REST server and the Cassandra DAOs.")
public class CassandraSpec extends Specification {
@Shared
ApplicationContext context
@Shared
CQLDataLoader cql
@Shared boolean initialized = false

// This is the server port that Spring picked. We use it in the REST URLs
// @Value('${local.server.port}')
@Shared
int serverPort

def setup() {
if (initialized) {
return
}

System.setProperty("spring.profiles.active", "test")
SpringApplication app = new SpringApplication(CassandraConfig.class)
app.headless = true
context = app.run(Application.class)
assert context
cql = new CQLDataLoader(context.getBean("session"))
serverPort = Integer.parseInt(context.environment.getProperty('server.port'))
println("Tomcat port: ${serverPort}")
initialized = true
}

... test methods here ...
}

最佳答案

脸掌!!!发布此内容后,我发现我需要添加 CassandraUnitDependencyInjectionTestExecutionListener。神奇的线条是:

@TestExecutionListeners(listeners = [ CassandraUnitDependencyInjectionTestExecutionListener, CassandraUnitTestExecutionListener, DependencyInjectionTestExecutionListener.class ]) 

之后,我能够在没有任何其他杂乱的情况下运行测试,并且我可以注入(inject)一个临时端口并在我的 RestTemplate URL 中使用它。问题解决了:-)

关于spring - 在 Spock 测试中加载 Spring 上下文*之前*如何启动嵌入式 Cassandra 服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33840156/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com