BookBorrowService { @Transactional public void applyBorrowRequest(Long id, Account borrower) { Book book = bookDao.findOne(id); if (!book.status.equals(Book.STATUS_IDLE)) { logger.error("User request the book not idle, user id:" + borrower.id + ",book id:" + id + ",status:" + book.status); throw new ServiceException("The book is not idle", ErrorCode.BOOK_STATUS_WRONG); } if (borrower.id.equals(book.owner.id)) { logger.error("User borrow the book himself, user id:" + borrower.id + ",book id:" + id); throw new ServiceException("User shouldn't borrower the book which is himeself", ErrorCode.BOOK_OWNERSHIP_WRONG); } book.status = Book.STATUS_REQUEST; book.borrower = borrower; bookDao.save(book); Message message = new Message(book.owner, String.format("Apply book <%s> request by %s", book.title, borrower.name), ClockUtil.currentDate()); messageDao.save(message); }  @Transactional void applyBorrowRequest(Long id, Account borrower); @Transactional void cancelBorrowRequest(Long id, Account borrower); @Transactional void markBookBorrowed(Long id, Account owner); @Transactional void rejectBorrowRequest(Long id, Account owner); @Transactional void markBookReturned(Long id, Account owner); @Transactional(readOnly = true) List<Book> listMyBorrowedBook(Long borrowerId, Pageable pageable);  }
@Test public void applyBorrowRequest() { Book book = new Book(1L); book.status = Book.STATUS_IDLE; book.owner = new Account(1L); Mockito.when(mockBookDao.findOne(1L)).thenReturn(book); service.applyBorrowRequest(1L, new Account(3L)); Mockito.verify(mockBookDao).save(Mockito.any(Book.class)); Mockito.verify(mockMessageDao).save(Mockito.any(Message.class)); }
@Test public void applyBorrowRequestWithError() { Book book = new Book(1L); book.status = Book.STATUS_IDLE; book.owner = new Account(1L); Mockito.when(mockBookDao.findOne(1L)).thenReturn(book); try { service.applyBorrowRequest(1L, new Account(1L)); fail("should fail here"); } catch (Exception e) { assertThat(e).hasMessageContaining("User shouldn't borrower the book which is himeself"); assertThat(appender.getLastMessage()).contains("user id:1,book id:1"); } Mockito.verify(mockBookDao, Mockito.never()).save(Mockito.any(Book.class)); book.status = Book.STATUS_REQUEST; try { service.applyBorrowRequest(1L, new Account(3L)); fail("should fail here"); } catch (Exception e) { assertThat(e).hasMessageContaining("The book is not idle"); assertThat(appender.getLastMessage()).contains("user id:3,book id:1,status:request"); } Mockito.verify(mockBookDao, Mockito.never()).save(Mockito.any(Book.class)); }