package com.nisum.BookInfo.controller; import com.nisum.BookInfo.dto.BookDto; import com.nisum.BookInfo.entity.Book; import com.nisum.BookInfo.mapper.BookMapper; import com.nisum.BookInfo.service.BookService; import com.nisum.BookInfo.validator.CommonServiceValidator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.web.reactive.server.WebTestClient; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.client.MockMvcWebTestClient.bindToController; @SpringBootTest class BookControllerTest { @Mock private BookService bookService; // Mock the BookService @Mock private CommonServiceValidator validatorService; // Mock ValidatorService for book validation @InjectMocks private BookController bookController; // The controller under test /* private BookDto validBookDto; private Book savedBook;*/ @BeforeEach public void setUp() { BookDto bookDto = new BookDto(1, "C++", "This is c++", "C publiser", "Test Author"); Book book = new Book(1, "C++", "This is c++", "C publiser", "Test Author"); //when(bookDao.saveBook(any(Book.class))).thenReturn(Mono.just(book)); MockitoAnnotations.openMocks(this); } @Test public void createBook_shouldReturnSuccess_whenBookIsValid() { BookDto bookDto = new BookDto(1, "C++", "This is c++", "C publiser", "Test Author"); Book book = new Book(1, "C++", "This is c++", "C publiser", "Test Author"); // Mock the validateBook() and saveBook() methods when(validatorService.isBookIdValid(bookDto.getBookId())).thenReturn(Mono.just(true)); // Validation passes when(validatorService.isBookNameValid(bookDto.getName())).thenReturn(Mono.just(true)); when(bookService.saveBook(bookDto)).thenReturn(Mono.just(book)); // Return saved book // Directly call the controller method (createBook) with the valid BookDto Mono<?> result = bookController.createBook(Mono.just(bookDto)); // Use StepVerifier to check the result StepVerifier.create(result) .expectNextMatches(response -> { // Assert that the response is a ResponseEntity with the expected message assertTrue(response instanceof ResponseEntity); ResponseEntity<?> responseEntity = (ResponseEntity<?>) response; assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); return true; }) .verifyComplete(); // Ensure the Mono completes without error } @Test public void createBook_shouldReturnError_whenValidationFails() { // Given: Create an invalid BookDto (for validation failure) BookDto invalidBookDto = new BookDto(1, "C++", "This is c++", "C publiser", "Test Author"); when(validatorService.isBookIdValid(invalidBookDto.getBookId())).thenReturn(Mono.just(true)); // Validation passes when(validatorService.isBookNameValid(invalidBookDto.getName())).thenReturn(Mono.just(true)); // Simulate a validation failure (Mono.error) when(bookService.saveBook(invalidBookDto)).thenReturn(Mono.error(new IllegalArgumentException("Invalid publiser data"))); // Directly call the controller method with invalid BookDto Mono<?> result = bookController.createBook(Mono.just(invalidBookDto)); // Use StepVerifier to verify that the error is propagated StepVerifier.create(result) .expectError(IllegalArgumentException.class) // Expect the error thrown by validation .verify(); } //for update case @Test void updateBook_ShouldReturnUpdatedBook_WhenIdIsValid() { BookDto bookDto = new BookDto(1, "C++", "This is c++", "C publiser", "Test Author"); Book book = new Book(1, "C++", "This is c++", "C publiser", "Test Author"); // Mock the validateBook() and saveBook() methods when(validatorService.isBookIdValid(bookDto.getBookId())).thenReturn(Mono.just(true)); // Validation passes when(validatorService.isBookNameValid(bookDto.getName())).thenReturn(Mono.just(true)); when(bookService.updateBook(any(Integer.class), any(BookDto.class))).thenReturn(Mono.just(book)); // Make a test call to the controller method Mono<?> result = bookController.updateBook(1, Mono.just(bookDto)); // StepVerifier to test the result StepVerifier.create(result) .expectNextMatches(response -> { // Assert that the response is a ResponseEntity with the expected message assertTrue(response instanceof ResponseEntity); ResponseEntity<?> responseEntity = (ResponseEntity<?>) response; assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); return true; }) .verifyComplete(); // } //for getAllBook @Test void getAllBooks_ShouldReturnListOfBooks() { Book book1 = new Book(1, "C++", "This is c++", "C publiser", "Test Author"); Book book2 = new Book(2, "Java", "This is Java", "Java publiser", "Test Java Author"); when(bookService.getAllBooks()).thenReturn(Flux.just(book1, book2)); // Call the controller method Flux<Book> result = bookController.getAllBooks(); // Verify the response using StepVerifier StepVerifier.create(result). expectNextMatches(book -> book.getBookId().equals(1)) . expectNextMatches(book -> book.getBookId().equals(2)) .verifyComplete(); // } //get single book @Test void getBookById_ShouldReturnBookWithStatusOk() { BookDto bookDto = new BookDto(1, "C++", "This is c++", "C publiser", "Test Author"); Book book = new Book(1, "C++", "This is c++", "C publiser", "Test Author"); when(validatorService.isBookIdValid(bookDto.getBookId())).thenReturn(Mono.just(true)); // Validation passes when(validatorService.isBookNameValid(bookDto.getName())).thenReturn(Mono.just(true)); when(bookService.getBookById(1)).thenReturn(Mono.just(book)); // Call the controller method Mono<?> result = bookController.getBookById(1); // Verify the response using StepVerifier StepVerifier.create(result) .expectNextMatches(response -> { // Assert that the response is a ResponseEntity with the expected message assertTrue(response instanceof ResponseEntity); ResponseEntity<?> responseEntity = (ResponseEntity<?>) response; assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); return true; }) .verifyComplete(); // } //delete @Test void deleteBook_ShouldReturnOkWhenDeletedSuccessfully() { BookDto bookDto = new BookDto(1, "C++", "This is c++", "C publiser", "Test Author"); Book book = new Book(1, "C++", "This is c++", "C publiser", "Test Author"); when(validatorService.isBookIdValid(bookDto.getBookId())).thenReturn(Mono.just(true)); // Validation passes when(validatorService.isBookNameValid(bookDto.getName())).thenReturn(Mono.just(true)); when(bookService.deleteBook(1)).thenReturn(Mono.empty()); // Call the controller method Mono<?> result = bookController.deleteBook(1); // Verify the response using StepVerifier StepVerifier.create(result) .expectNextMatches(response -> { // Assert that the response is a ResponseEntity with the expected message assertTrue(response instanceof ResponseEntity); ResponseEntity<?> responseEntity = (ResponseEntity<?>) response; assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); return true; }) .verifyComplete(); // } }