Skip to content

Commit 00aa19d

Browse files
committed
Add TDD for success and custom ResourceNotFound exception
1 parent 0bcb2a0 commit 00aa19d

File tree

1 file changed

+63
-4
lines changed

1 file changed

+63
-4
lines changed

src/test/java/com/codesungrape/hmcts/bookapi/BookServiceTest.java

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.codesungrape.hmcts.bookapi.dto.BookRequest;
44
import com.codesungrape.hmcts.bookapi.entity.Book;
5+
import com.codesungrape.hmcts.bookapi.exception.ResourceNotFoundException;
56
import com.codesungrape.hmcts.bookapi.repository.BookRepository;
67
import com.codesungrape.hmcts.bookapi.service.BookService;
78
import org.junit.jupiter.api.BeforeEach;
@@ -14,12 +15,14 @@
1415
import org.mockito.Mock;
1516
import org.mockito.junit.jupiter.MockitoExtension;
1617

18+
import java.util.Optional;
1719
import java.util.UUID;
1820
import java.util.stream.Stream;
1921

2022
import static org.junit.jupiter.api.Assertions.assertEquals;
2123
import static org.junit.jupiter.api.Assertions.assertNotNull;
2224
import static org.junit.jupiter.api.Assertions.assertThrows;
25+
import static org.junit.jupiter.api.Assertions.assertTrue;
2326
import static org.mockito.ArgumentMatchers.any;
2427
import static org.mockito.Mockito.never;
2528
import static org.mockito.Mockito.when;
@@ -53,6 +56,10 @@ class BookServiceTest {
5356
private Book persistedBook;
5457
private UUID testId;
5558

59+
// --------------------------------------
60+
// Parameter Sources
61+
// --------------------------------------
62+
5663
// Provide test data, static method: can be called without creating an object.
5764
private static Stream<Arguments> provideLongFieldTestCases() {
5865
UUID testId = UUID.randomUUID();
@@ -84,8 +91,9 @@ private static Stream<Arguments> provideLongFieldTestCases() {
8491
);
8592
}
8693

87-
// --------- TESTS ------------
88-
94+
// --------------------------------------
95+
// Tests
96+
// --------------------------------------
8997
@BeforeEach
9098
void setUp() {
9199
testId = UUID.randomUUID();
@@ -109,6 +117,9 @@ void setUp() {
109117
.build();
110118
}
111119

120+
// --------------------------------------
121+
// Tests: createBook
122+
// --------------------------------------
112123
@Test
113124
void testCreateBook_Success() {
114125

@@ -192,7 +203,6 @@ void testCreateBook_BlankTitle_ThrowsException() {
192203
);
193204
}
194205

195-
// --------- Repository failures
196206
@Test
197207
void testCreateBook_RepositoryFailure_ThrowsException() {
198208
// Arrange
@@ -213,7 +223,10 @@ void testCreateBook_RepositoryFailure_ThrowsException() {
213223
@ParameterizedTest(name = "{0}") // Display the test name
214224
@MethodSource("provideLongFieldTestCases")
215225
void testCreateBook_VeryLongFields_Success(
216-
String testName, BookRequest request, Book expectedBook) {
226+
String testName,
227+
BookRequest request,
228+
Book expectedBook
229+
) {
217230

218231
// Arrange
219232
when(testBookRepository.save(any(Book.class))).thenReturn(expectedBook);
@@ -260,4 +273,50 @@ void testCreateBook_SpecialCharactersInTitle_Success() {
260273
// Did the service perform the correct action on its dependency?
261274
verify(testBookRepository, times(1)).save(any(Book.class));
262275
}
276+
277+
// --------------------------------------------------------------------------------------------
278+
// Tests: deleteBookById(UUID)
279+
// -------------------------------------------------------------------------------------------
280+
281+
@Test
282+
void testDelete_Book_ShouldThrowException_WhenIdNotFound() {
283+
284+
// Arrange: As goal is to test what happens when the resource doesn't exist,
285+
// we intentionally simulate DB returning NO result
286+
when(testBookRepository.findByIdAndDeletedFalse(testId)).thenReturn(Optional.empty());
287+
288+
// ACT and ASSERT: throw ResourceNotFoundException when calling the delete method.
289+
assertThrows(
290+
// custom exception to reflect business rules vs technical problem
291+
ResourceNotFoundException.class,
292+
() -> testBookService.deleteBookById(testId)
293+
);
294+
295+
// Assert: ensure the save method was NEVER called.
296+
// proves delete business logic halts immediately when the resource isn't found.
297+
verify(testBookRepository, never()).save(any(Book.class));
298+
}
299+
300+
@Test
301+
void testDeleteBookById_Success() {
302+
303+
// Arrange:
304+
persistedBook.setDeleted(false); // ensure starting state
305+
306+
when(testBookRepository.findByIdAndDeletedFalse(testId))
307+
.thenReturn(Optional.of(persistedBook));
308+
309+
when(testBookRepository.save(any(Book.class)))
310+
.thenReturn(persistedBook);
311+
312+
// Act: call the service method we are testing
313+
testBookService.deleteBookById(testId);
314+
315+
// Assert: the entity was marked deleted
316+
assertTrue(persistedBook.isDeleted());
317+
318+
// Assert: repository methods were called correctly
319+
verify(testBookRepository, times(1)).findByIdAndDeletedFalse(testId);
320+
verify(testBookRepository, times(1)).save(persistedBook);
321+
}
263322
}

0 commit comments

Comments
 (0)