use*_*270 4 spring cassandra spock spring-data spring-boot
在我的一个集成测试中,我似乎遇到了一个棘手的情况.我有一个基于Spring Boot/Spring MVC和Cassandra DB的REST服务器.我正在使用spring-data-cassandra jar文件来启用POJO通过CassandraTemplate通过CrudRepository实现插入到DB中.应用程序工作正常,我可以进行REST调用,框架正确地将我的表单数据转换为POJO并将数据插入到数据库中.到现在为止还挺好.
我要做的是编写一个执行整个堆栈的集成测试.显然我不想依赖外部数据库,所以我使用了cassandra-unit-spring中的EmbeddedCassandra 并通过Spock测试驱动它.我遇到的问题似乎与@ContextConfiguration批注中定义的SpringApplicationContextLoader和@TestExecutionListener批注中定义的CassandraUnitTestExecutionListener类之间的某种排序冲突有关.由于这是一个Spock测试,它需要SpringApplicationContextLoader类来自动启动Spring Boot服务器.但是,它在Cassandra服务器启动之前会这样做,这会导致集群/会话bean无法加载,因为它们显然会在创建时立即尝试联系服务器.我已经尝试了很多东西组合,我的头在旋转.我不得不求助于我认为非常难看的解决方案.我有一个setup()方法,它使用布尔值来确保上下文和Spring Boot应用程序只运行一次.我尝试将它放在一个setupSpec()方法中,该方法每个测试类只运行一次,但是没有用(有些问题22).如果我尝试@Autowire上下文,那么它会在CassandraServer启动之前注入.正如我所提到的,我尝试了很多不同的东西.
这个解决方案有效,但它让我感到困惑的是,我无法通过注释和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 ...
}
Run Code Online (Sandbox Code Playgroud)
脸掌!!! 发布后,我发现我需要添加CassandraUnitDependencyInjectionTestExecutionListener.神奇的线条是:
@TestExecutionListeners(listeners = [ CassandraUnitDependencyInjectionTestExecutionListener, CassandraUnitTestExecutionListener, DependencyInjectionTestExecutionListener.class ])
Run Code Online (Sandbox Code Playgroud)
之后我能够在没有任何其他kludges的情况下运行测试,我可以注入一个短暂的端口并在我的RestTemplate URL中使用它.问题解决了 :-)
| 归档时间: |
|
| 查看次数: |
2661 次 |
| 最近记录: |