skip to Main Content

I have a Spring application that I am trying to test with EmbededRedis. So I created a component like below to Initialize and kill redis after test.

@Component
public class EmbededRedis {

  @Value("${spring.redis.port}")
  private int redisPort;

  private RedisServer redisServer;

  @PostConstruct
  public void startRedis() throws IOException {
    redisServer = new RedisServer(redisPort);
    redisServer.start();
  }

  @PreDestroy
  public void stopRedis() {
    redisServer.stop();
  }
}

But now I am facing a weird issue. Because spring caches the context, PreDestroy doesnt get called everytime after my test is executed, but for some reason, @PostConstruct gets called, and EmbededRedis tries to start the running redis server again and again, which is creatimg issues in the execution.

Is there a way to handle this situation by any mean?

Update
This is how I am primarily defining my tests.

@SpringBootTest(classes = {SpringApplication.class})
@ActiveProfiles("test")
public class RedisApplicationTest {

2

Answers


  1. Chosen as BEST ANSWER

    So I debuged the ContextInitialization as suggested by @M. Deinum.

    For me, the porblem was, Our application was mocking different classes in order to mix mocking with Spring context. Now, when you use mocks, MockitoContextInitializer also becomes part of your cache key, which results in cache miss. Reason is, The classes under mock are obviously different for different test classes.

    Looking at the situation, I preferred to go ahead with @DirtiesContext to invalidate the contest after the test is done, so that I can reinitialize the context later on for different test.

    Note @DirtiesContext is in a way recommended to be avoided as it slows down your tests.


  2. Ditch the class and write an @Configuration class which exposed RedisServer as a bean.

    @Configuration
    public void EmbeddedRedisConfiguration {
    
       @Bean(initMethod="start", destroyMethod="stop")
       public RedisServer embeddedRedisServer(@Value("${spring.redis.port}") int port) {
          return new RedisServer(port);
       }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search