我试图注入一个WebTestClient,以使用Spring Webflux实现一些集成测试。
我必须加载使用此配置运行的redis嵌入式软件:
@Configuration
@Profile("test")
public class EmbeddedRedisConfiguration {
private RedisServer redisServer;
public EmbeddedRedisConfiguration(@Value("${spring.redis.port}") int redisPort) {
this.redisServer = new RedisServer(redisPort);
}
@PostConstruct
public void postConstruct() {
redisServer.start();
}
@PreDestroy
public void preDestroy() {
redisServer.stop();
}
@Bean
@Primary
public ReactiveRedisOperations<String, Foo> redisOperations(@Qualifier("redissonConnectionFactory") ReactiveRedisConnectionFactory factory) {
Jackson2JsonRedisSerializer<Foo> serializer = new Jackson2JsonRedisSerializer<>(Foo.class);
RedisSerializationContext.RedisSerializationContextBuilder<String, Foo> builder = RedisSerializationContext.newSerializationContext(new StringRedisSerializer());
RedisSerializationContext<String, Foo> context = builder.value(serializer).build();
return new ReactiveRedisTemplate<>(factory, context);
}
}
上课
@ExtendWith(SpringExtension.class)
@SpringBootTest
@ActiveProfiles("test")
public class FooControllerIT {
@Autowired
WebTestClient webTestClient;
@Test
public void testSomething() {
// do something
}
}
我收到此错误:
No qualifying bean of type 'org.springframework.test.web.reactive.server.WebTestClient' available: expected at least 1 bean which qualifies as autowire candidate
如果我改变这一行
@SpringBootTest
到这条线
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
WebTestClient可用于自动装配,但是应用程序会在我的测试配置文件配置之前启动,无法连接到嵌入式Redis:
Factory method 'redisson' threw exception; nested exception is org.redisson.client.RedisConnectionException: Unable to connect to Redis server: localhost/127.0.0.1:6379
有没有注入WebTestClient而不启动web环境的方法,还是有办法在其他事情之前加载我的嵌入式redis配置?
编辑
看来问题是那js RedissonAutoConfiguration 是
装
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Spring Boot测试中,使用@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
确实会启动一个完整的Web服务器,这可能与你希望先初始化嵌入式Redis再进行其他服务启动的顺序相冲突。为了解决这个问题,你可以采取以下策略:
Testcontainers 是一个强大的库,允许在JUnit测试中运行轻量级的 Docker 容器。对于你的需求,可以使用 Redis Testcontainer 来确保 Redis 在所有其他服务之前启动。
首先,添加 Testcontainers 的依赖到你的项目中(Maven 示例):
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>redis</artifactId>
<scope>test</scope>
</dependency>
然后,在测试类中使用 Testcontainers 初始化 Redis:
@SpringBootTest
@ActiveProfiles("test")
public class FooControllerIT {
static {
GenericContainer<?> redis = new GenericContainer<>("redis:latest")
.withExposedPorts(6379);
redis.start();
System.setProperty("spring.redis.host", redis.getHost());
System.setProperty("spring.redis.port", String.valueOf(redis.getMappedPort(6379)));
}
@Autowired
private WebTestClient webTestClient;
// ... 测试方法
}
这样,每次测试运行时,都会先启动一个 Redis 容器,并设置相应的环境变量供Spring应用使用,确保了Redis在应用启动前已经就绪。
如果你不想使用Docker和Testcontainers,可以通过自定义TestExecutionListener
来控制Spring Boot应用程序的启动顺序,确保Redis配置在Web服务器启动之前完成初始化。
创建一个监听器类,覆盖beforeTestClass
方法来启动RedisServer:
public class EmbeddedRedisStartupListener extends AbstractTestExecutionListener {
@Override
public void beforeTestClass(TestContext testContext) throws Exception {
ConfigurableApplicationContext context = testContext.getApplicationContext();
EmbeddedRedisConfiguration config = context.getBean(EmbeddedRedisConfiguration.class);
config.postConstruct(); // 手动启动RedisServer
}
}
然后,在测试类上使用@TestExecutionListeners
注解指定这个监听器:
@TestExecutionListeners(listeners = {EmbeddedRedisStartupListener.class, DependencyInjectionTestExecutionListener.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class FooControllerIT {
// ... 测试代码
}
这种方法需要手动控制RedisServer的生命周期,确保它在测试结束时被正确关闭。
上述两种方法都能帮助你在不直接启动Web环境的情况下注入WebTestClient
,同时确保嵌入式Redis配置得以正确加载。Testcontainers提供了一种更加隔离且灵活的解决方案,而自定义TestExecutionListener则是一种更直接介入Spring测试生命周期的方法。根据你的具体需求和偏好选择合适的方法。