Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Testes de API falham ao utilizar o Cache do Redis

Tentando realizar os testes em containers como demonstrado em aula, os testes falham sempre que passam (ou tentam) pelo Redis.

Algumas informações sobre o erro:

Resolved Exception: Type = org.springframework.data.redis.RedisConnectionFailureException"

e a mensagem de retorno no body:

 Body = {"timeStamp":"2023-09-12T18:01:07.0316679","status":500,"error":"**INTERNAL_SERVER_ERROR","message":"Unable to connect to Redis","path":""**}

Sobre a classe de teste, segue abaixo o essencial:

@AutoConfigureMockMvc

class TopicoControllerTest(
    @Autowired private val mockMvc: MockMvc,
    @Autowired private val tokenService: TokenService,
) : DatabaseContainerConfiguration() {

    private var token: String? = null

    companion object {
        private const val URI = "/topicos"
    }

    @BeforeEach
    fun setup() {
        token = gerarToken()
    }

    @Test
    @DisplayName("Deve retornar 200 quando chamar /topicos com token válido e role valida")
    fun listar1() {
        mockMvc.get(URI) {
            headers { token?.let { setBearerAuth(it) } }
        }
            .andExpect { status { isOk() } }
    }

    private fun gerarToken(): String { 
        val usuario = UsuarioTest.buildToToken() // este usuario tem os mesmos dados do registrado no banco.
        return tokenService.generateToken(usuario.email)
    }
}

e a classe de configuração dos containers:

@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
abstract class DatabaseContainerConfiguration {

    companion object {

        @Container
        private val mySQLContainer = MySQLContainer<Nothing>("mysql:8.0").apply {
            withExposedPorts(3306)
            withDatabaseName("testeDB")
            withUsername("teste")
            withPassword("13456")
            withReuse(true)
        }

        @Container
        val rediscontainer = GenericContainer<Nothing>("redis:latest").apply {
            withExposedPorts(6379)
            dependsOn(mySQLContainer)
        }


        @JvmStatic
        @DynamicPropertySource
        fun properties(registry: DynamicPropertyRegistry) {
            registry.add("spring.datasource.url", mySQLContainer::getJdbcUrl)
            registry.add("spring.datasource.username", mySQLContainer::getUsername)
            registry.add("spring.datasource.password", mySQLContainer::getPassword)

            registry.add("spring.redis.host", rediscontainer::getHost)
            registry.add("spring.redis.port", rediscontainer::getFirstMappedPort)
        }
    }

}

Pelo observado, creio que os testes automatizados não estão conseguindo conectar ao cache do Redis. Porém, ao executar manualmente e testar via Postman, tudo funciona.

4 respostas

editado na mensagem inicial

Olá, Felipe!

Pelo que entendi, seus testes estão passando localmente, mas falhando quando executados pelo Github Actions, certo? Isso é um problema comum e pode ser causado por várias razões.

Uma das razões mais prováveis é que o ambiente de teste local e o ambiente de teste do Github Actions podem não ser exatamente iguais. Por exemplo, pode haver diferenças na configuração do banco de dados, nas variáveis de ambiente, na versão do JDK, entre outros.

No seu caso, os testes estão falhando com um status 500, o que indica um erro interno do servidor. Isso sugere que algo pode estar errado com o servidor ou com a aplicação quando ela é executada no Github Actions.

Olhando para o seu código, vejo que você está usando o DatabaseContainerConfiguration para configurar o banco de dados para seus testes. Isso é ótimo para garantir que seus testes sejam independentes e possam ser executados em qualquer ambiente. No entanto, pode ser que algo esteja errado com essa configuração quando ela é executada no Github Actions.

Uma coisa que você pode tentar é adicionar logs ao seu código para ajudar a identificar o que está causando o erro 500. Você pode adicionar logs no seu controlador, no serviço de token e na configuração do banco de dados. Depois, você pode verificar os logs quando os testes são executados no Github Actions para ver se há algo estranho acontecendo.

Outra coisa que você pode tentar é verificar se o usuário e o token usados nos testes estão corretos e têm as permissões adequadas. Se o usuário ou o token estiverem errados, isso pode causar um erro 500.

Espero que essas sugestões te ajudem a resolver o problema. Lembre-se, a depuração é uma parte importante do desenvolvimento de software e, às vezes, pode ser um pouco complicada, mas não desanime! Você está no caminho certo!

Espero ter ajudado e bons estudos!

Matheus, editei a postagem original com uma correção. Os testes MANUAIS passam, mas os automatizados (deixando as classes de testes gerenciarem os containers) falham

solução!

Com a alteração da versão do spring boot, a configuração do Redis precisa ser:

       @JvmStatic
        @DynamicPropertySource
        fun properties(registry: DynamicPropertyRegistry) {
            registry.add("spring.datasource.url", mySQLContainer::getJdbcUrl)
            registry.add("spring.datasource.username", mySQLContainer::getUsername)
            registry.add("spring.datasource.password", mySQLContainer::getPassword)

            registry.add("spring.data.redis.host", rediscontainer::getHost)
            registry.add("spring.data.redis.port", rediscontainer::getFirstMappedPort)
        }
    }