Quantcast
Channel: Active questions tagged redis+java - Stack Overflow
Viewing all articles
Browse latest Browse all 2204

How can I disable REDIS for my Spring Boot integration tests? [duplicate]

$
0
0

I'm trying to disable REDIS in the context of my integration tests, but I'm not having success.

Whenever I run the integration tests, SpringBoot starts saving the test data inside REDIS, which causes inconsistency and the tests fail.

I have the following classes:

GetDetailedBookDataIT contains the integration test

@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)@ActiveProfiles("test")public class GetDetailedBookDataIT {    @LocalServerPort    private int port;    @Autowired    private BookRest bookRest;    @Autowired    private RestTemplate restTemplate;    @Mock    private GutendexHttpClient gutendexHttpClient;    @InjectMocks    private GetDetailedBookData getDetailedBookData;    @Test    public void it_should_get_detailed_book_data() {        String saveBookurl = "http://localhost:" + port +"/books/save";        Integer bookId = 1;        Integer rating = 3;        BookReviewDto bookReviewDto = new BookReviewDtoBuilder().setBookId(bookId).setRating(rating).create();        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        restTemplate.postForEntity(saveBookurl, bookReviewDto, String.class);        ResponseEntity<DetailedBookDataDto> response =                restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        assertEquals(1, response.getBody().id);        assertEquals("Book data retrieved successfully.", response.getBody().responseMessage);    }    @Test    public void it_should_return_error_message_if_book_id_is_below_zero() {        Integer bookId = -1;        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpClientErrorException e){            assertTrue(e.getMessage().contains("Book id cannot be negative or zero."));            assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode());        }    }    @Test    public void it_should_return_error_message_if_book_id_is_zero() {        Integer bookId = 0;        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpClientErrorException e){            assertTrue(e.getMessage().contains("Book id cannot be negative or zero."));            assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode());        }    }    @Test    public void it_should_return_error_message_if_no_book_is_found_for_given_id() {        Integer bookId = 5;        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpClientErrorException e){            assertTrue(e.getMessage().contains("No book review found for this book."));            assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());        }    }    @Test    public void it_should_return_error_message_if_gutendex_api_is_unavaiable(){        openMocks(this);        String saveBookurl = "http://localhost:" + port +"/books/save";        Integer bookId = 5;        BookReviewDto bookReviewDto = new BookReviewDtoBuilder().setBookId(bookId).create();        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        when(gutendexHttpClient.getBookBasedOnId(any())).thenThrow(new ResourceAccessException("Simulated Exception"));        restTemplate.postForEntity(saveBookurl, bookReviewDto, String.class);        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpClientErrorException e){            assertTrue(e.getMessage().contains("Guntendex API is not available."));            assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode());        }    }    @Test    public void it_should_return_error_message_when_gutendex_api_returns_null_for_given_id(){        openMocks(this);        String saveBookurl = "http://localhost:" + port +"/books/save";        Integer bookId = 5;        BookReviewDto bookReviewDto = new BookReviewDtoBuilder().setBookId(bookId).create();        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        when(gutendexHttpClient.getBookBasedOnId(any())).thenReturn(new GutendexSearchResultDtoBuilder().createWithBooksNull());        restTemplate.postForEntity(saveBookurl, bookReviewDto, String.class);        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpClientErrorException e){            assertTrue(e.getMessage().contains("Book data not found in Gutendex API."));            assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());        }    }    @Test    public void it_should_return_error_message_when_gutendex_api_returns_empty_list_for_given_id(){        openMocks(this);        String saveBookurl = "http://localhost:" + port +"/books/save";        Integer bookId = 5;        BookReviewDto bookReviewDto = new BookReviewDtoBuilder().setBookId(bookId).create();        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        when(gutendexHttpClient.getBookBasedOnId(any())).thenReturn(new GutendexSearchResultDtoBuilder().createWithBooksEmpty());        restTemplate.postForEntity(saveBookurl, bookReviewDto, String.class);        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpClientErrorException e){            assertTrue(e.getMessage().contains("Book data not found in Gutendex API."));            assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());        }    }    @Test    public void it_should_return_error_message_when_unexpected_error_occurs(){        openMocks(this);        String saveBookurl = "http://localhost:" + port +"/books/save";        Integer bookId = 5;        BookReviewDto bookReviewDto = new BookReviewDtoBuilder().setBookId(bookId).create();        String getDetailedBookDataApiUrl = "http://localhost:" + port +"/books/detailed?id=" + bookId;        when(gutendexHttpClient.getBookBasedOnId(any())).thenThrow(new RuntimeException("Simulated Exception"));        restTemplate.postForEntity(saveBookurl, bookReviewDto, String.class);        try{            restTemplate.getForEntity(getDetailedBookDataApiUrl, DetailedBookDataDto.class);        }catch (HttpServerErrorException e){            assertTrue(e.getMessage().contains("An unexpected error occurred, please try again, " +"if the error persists contact support"));            assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, e.getStatusCode());        }    }}

And then I have this service class that contains some logic

@Servicepublic class GetDetailedBookData {    private BookReviewRepository bookReviewRepository;    private GutendexHttpClient gutendexHttpClient;    public GetDetailedBookData(BookReviewRepository bookReviewRepository, GutendexHttpClient gutendexHttpClient) {        this.bookReviewRepository = bookReviewRepository;        this.gutendexHttpClient = gutendexHttpClient;    }    @Cacheable(value = "detailedBook")    public DetailedBookDataDto get(Integer bookId){        if(bookId == null){            return new DetailedBookDataDto("Book id is required.", HttpStatus.BAD_REQUEST);        } else if(bookId <= 0){            return new DetailedBookDataDto("Book id cannot be negative or zero.", HttpStatus.BAD_REQUEST);        }        try{            List<BookReview> bookReviewList = bookReviewRepository.findByBookId(bookId);            if(bookReviewList.isEmpty()){                return new DetailedBookDataDto("No book review found for this book.",                        HttpStatus.NOT_FOUND);            }            GutendexSearchResultDto bookBasedOnId;            try {                bookBasedOnId = gutendexHttpClient.getBookBasedOnId(bookId);            }catch (ResourceAccessException e){                e.printStackTrace();                return new DetailedBookDataDto("Guntendex API is not available.",                        HttpStatus.REQUEST_TIMEOUT);            }            if(bookBasedOnId.books == null || bookBasedOnId.books.isEmpty()){                return new DetailedBookDataDto("Book data not found in Gutendex API.",                        HttpStatus.NOT_FOUND);            }            DetailedBookDataDto detailedBookDataDto = createDetailedBookDataDto(bookReviewList, bookBasedOnId);            detailedBookDataDto.responseMessage = "Book data retrieved successfully.";            detailedBookDataDto.httpStatus = HttpStatus.OK;            return detailedBookDataDto;        }catch (Exception e){            e.printStackTrace();            return new DetailedBookDataDto("An unexpected error occurred, please try again, " +"if the error persists contact support", HttpStatus.INTERNAL_SERVER_ERROR);        }    }    private DetailedBookDataDto createDetailedBookDataDto(List<BookReview> bookReviewList, GutendexSearchResultDto bookBasedOnId) {        Double avgRating = bookReviewList.stream()                .mapToInt(BookReview::getRating)                .average()                .orElse(0);        BigDecimal roundedAvgRating = new BigDecimal(avgRating).setScale(2, RoundingMode.HALF_UP);        List<String> listOfReviews = bookReviewList.stream().map(BookReview::getReview).toList();        GutendexBookDto bookInformation = bookBasedOnId.books.get(0);        DetailedBookDataDto detailedBookDataDto = new DetailedBookDataDto(bookInformation.id, bookInformation.title, bookInformation.authors,                bookInformation.languages, bookInformation.download_count, roundedAvgRating.doubleValue(), listOfReviews);        detailedBookDataDto.responseMessage = "Book data retrieved successfully.";        return detailedBookDataDto;    }}

How do I know that the problem with my tests is REDIS? Why when I delete the @Cacheable(value = "detailedBook") line inside my service, the tests work again

I have two properties, one for testing and one for development.

The development properties:

# PostgreSQL connection propertiesspring.datasource.url=jdbc:postgresql://localhost:5432/postgresspring.datasource.username=postgresspring.datasource.password=postgresspring.datasource.driver-class-name=org.postgresql.Driverspring.jpa.hibernate.ddl-auto=createspring.jpa.show-sql=true#Redisspring.redis.host=localhostspring.redis.port=6380logging.level.org.springframework.data.redis=DEBUGspring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfigurationspring.data.redis.repositories.enabled=falsegutendex.baseurl=https://gutendex.com/books

And the Test properties:

spring.datasource.url=jdbc:h2:mem:testdbspring.datasource.driverClassName=org.h2.Driverspring.datasource.username=saspring.datasource.password=passwordspring.jpa.database-platform=org.hibernate.dialect.H2Dialectspring.jpa.hibernate.ddl-auto=createspring.jpa.show-sql=truespring.h2.console.enabled=truespring.h2.console.path=/h2-consolespring.data.redis.repositories.enabled=falsegutendex.baseurl=https://gutendex.com/books

I've already tried:

  • Make redis point to a non-existent address within the test propertiesspring.redis.host=non-existing-host spring.redis.port=9999
  • Disable Redis Auto-Configure within test properties
  • Add this line of code to my class that contains the integration test@TestPropertySource(properties = {"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration"})

And many other things I can't remember.

If anyone can help me I would be very grateful, thanks!


Viewing all articles
Browse latest Browse all 2204

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>