BAEL-4810: First Review Improvements. Added test cases and fixed some indentations
This commit is contained in:
parent
a6b215d7a3
commit
c5e0771e1d
|
@ -37,7 +37,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.tomcat.embed</groupId>
|
<groupId>org.apache.tomcat.embed</groupId>
|
||||||
<artifactId>tomcat-embed-jasper</artifactId>
|
<artifactId>tomcat-embed-jasper</artifactId>
|
||||||
<!--uncomment below if external deployment-->
|
<!--uncomment below if deploying in web container-->
|
||||||
<!--<scope>provided</scope>-->
|
<!--<scope>provided</scope>-->
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -50,12 +50,29 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--uncomment below if external deployment-->
|
<!--uncomment below if deploying in web container-->
|
||||||
<!--<dependency>-->
|
<!--<dependency>-->
|
||||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||||
<!-- <artifactId>spring-boot-starter-tomcat</artifactId>-->
|
<!-- <artifactId>spring-boot-starter-tomcat</artifactId>-->
|
||||||
<!-- <scope>provided</scope>-->
|
<!-- <scope>provided</scope>-->
|
||||||
<!--</dependency>-->
|
<!--</dependency>-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit-jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -80,7 +97,8 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<jstl.version>1.2</jstl.version>
|
<jstl.version>1.2</jstl.version>
|
||||||
<spring-boot.version>2.4.0</spring-boot.version>
|
<junit-jupiter.version>5.7.1</junit-jupiter.version>
|
||||||
|
<spring-boot.version>2.4.4</spring-boot.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -3,8 +3,8 @@ package com.baeldung.boot.jsp;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringBootConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import com.baeldung.boot.jsp.repository.BookRepository;
|
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||||
|
@ -12,7 +12,6 @@ import com.baeldung.boot.jsp.repository.impl.InMemoryBookRepository;
|
||||||
import com.baeldung.boot.jsp.repository.model.BookData;
|
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan(basePackages = "com.baeldung.boot.jsp")
|
|
||||||
public class SpringBootJspConfiguration {
|
public class SpringBootJspConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -22,9 +21,9 @@ public class SpringBootJspConfiguration {
|
||||||
|
|
||||||
private static Map<String, BookData> initialBookData() {
|
private static Map<String, BookData> initialBookData() {
|
||||||
Map<String, BookData> initData = new HashMap<>();
|
Map<String, BookData> initData = new HashMap<>();
|
||||||
initData.put("ISBN-TEST-1", new BookData("ISBN-TEST-1", "Book 1", "Book 1 Author"));
|
initData.put("ISBN-1", new BookData("ISBN-1", "Book 1", "Book 1 Author"));
|
||||||
initData.put("ISBN-TEST-2", new BookData("ISBN-TEST-2", "Book 2", "Book 2 Author"));
|
initData.put("ISBN-2", new BookData("ISBN-2", "Book 2", "Book 2 Author"));
|
||||||
initData.put("ISBN-TEST-3", new BookData("ISBN-TEST-3", "Book 3", "Book 3 Author"));
|
initData.put("ISBN-3", new BookData("ISBN-3", "Book 3", "Book 3 Author"));
|
||||||
return initData;
|
return initData;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,22 +2,20 @@
|
||||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Add Book</title>
|
<title>Add Book</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<c:if test="${addBookSuccess}">
|
||||||
<c:if test="${addBookSuccess}">
|
|
||||||
<div>Successfully added Book with ISBN: ${savedBook.isbn}</div>
|
<div>Successfully added Book with ISBN: ${savedBook.isbn}</div>
|
||||||
</c:if>
|
</c:if>
|
||||||
|
|
||||||
<c:url var="add_book_url" value="/book/addBook"/>
|
<c:url var="add_book_url" value="/book/addBook"/>
|
||||||
<form:form action="${add_book_url}" method="post" modelAttribute="book">
|
<form:form action="${add_book_url}" method="post" modelAttribute="book">
|
||||||
<form:label path="isbn">ISBN: </form:label> <form:input type="text" path="isbn"/>
|
<form:label path="isbn">ISBN: </form:label> <form:input type="text" path="isbn"/>
|
||||||
<form:label path="name">Book Name: </form:label> <form:input type="text" path="name"/>
|
<form:label path="name">Book Name: </form:label> <form:input type="text" path="name"/>
|
||||||
<form:label path="author">Author Name: </form:label> <form:input path="author"/>
|
<form:label path="author">Author Name: </form:label> <form:input path="author"/>
|
||||||
<input type="submit" value="submit"/>
|
<input type="submit" value="submit"/>
|
||||||
</form:form>
|
</form:form>
|
||||||
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
|
@ -7,12 +7,12 @@
|
||||||
--%>
|
--%>
|
||||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Error</title>
|
<title>Error</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Reference: ${ref}</p>
|
<p>Reference: ${ref}</p>
|
||||||
<p>Error Message: ${message}</p>
|
<p>Error Message: ${message}</p>
|
||||||
<p>Object: ${object}</p>
|
<p>Object: ${object}</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>View Books</title>
|
<title>View Books</title>
|
||||||
|
|
||||||
<link href="<c:url value="/css/common.css"/>" rel="stylesheet" type="text/css">
|
<link href="<c:url value="/css/common.css"/>" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
</head>
|
<body>
|
||||||
<body>
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -26,5 +24,5 @@
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,93 @@
|
||||||
|
package com.baeldung.boot.jsp.controller;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.hasProperty;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||||
|
import com.baeldung.boot.jsp.repository.impl.InMemoryBookRepository;
|
||||||
|
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
@ContextConfiguration
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class BookControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BookRepository bookRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void whenAddBook_thenBookSaved() throws Exception {
|
||||||
|
MockHttpServletRequestBuilder addBookRequest = MockMvcRequestBuilders.post("/book/addBook")
|
||||||
|
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
|
.param("isbn", "isbn1")
|
||||||
|
.param("name", "name1")
|
||||||
|
.param("author", "author1");
|
||||||
|
mockMvc.perform(addBookRequest)
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
Optional<BookData> storedBookOpt = bookRepository.findById("isbn1");
|
||||||
|
assertTrue(storedBookOpt.isPresent());
|
||||||
|
assertEquals("name1", storedBookOpt.get()
|
||||||
|
.getName());
|
||||||
|
assertEquals("author1", storedBookOpt.get()
|
||||||
|
.getAuthor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void givenAlreadyExistingBook_whenAddBook_thenShowErrorPage() throws Exception {
|
||||||
|
MockHttpServletRequestBuilder addBookRequest = MockMvcRequestBuilders.post("/book/addBook")
|
||||||
|
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
|
.param("isbn", "isbn1")
|
||||||
|
.param("name", "name1")
|
||||||
|
.param("author", "author1");
|
||||||
|
ResultActions addBookResult = mockMvc.perform(addBookRequest);
|
||||||
|
|
||||||
|
addBookResult.andExpect(view().name("error-book"))
|
||||||
|
.andExpect(model().attribute("ref", "isbn1"))
|
||||||
|
.andExpect(model().attribute("object", hasProperty("isbn", equalTo("isbn1"))))
|
||||||
|
.andExpect(model().attribute("message", "Cannot add an already existing book"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan("com.baeldung.boot.jsp")
|
||||||
|
static class ContextConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public BookRepository provideBookRepository() {
|
||||||
|
return new InMemoryBookRepository(Collections.emptyMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.baeldung.boot.jsp.controller;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.AdditionalAnswers;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
import com.baeldung.boot.jsp.dto.Book;
|
||||||
|
import com.baeldung.boot.jsp.service.BookService;
|
||||||
|
|
||||||
|
@WebMvcTest(BookController.class)
|
||||||
|
class BookControllerUnitTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private BookService bookService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenViewBooks_thenReturnBooksView() throws Exception {
|
||||||
|
when(bookService.getBooks()).thenReturn(existingBooks());
|
||||||
|
ResultActions viewBooksResult = mockMvc.perform(get("/book/viewBooks"));
|
||||||
|
|
||||||
|
viewBooksResult.andExpect(view().name("view-books"))
|
||||||
|
.andExpect(model().attribute("books", hasSize(3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddBookView_thenReturnAddBooksView() throws Exception {
|
||||||
|
ResultActions addBookViewResult = mockMvc.perform(get("/book/addBook"));
|
||||||
|
|
||||||
|
addBookViewResult.andExpect(view().name("add-book"))
|
||||||
|
.andExpect(model().attribute("book", isA(Book.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddBookPost_thenRedirectToAddBookView() throws Exception {
|
||||||
|
when(bookService.addBook(any(Book.class))).thenAnswer(AdditionalAnswers.returnsFirstArg());
|
||||||
|
MockHttpServletRequestBuilder addBookRequest = MockMvcRequestBuilders.post("/book/addBook")
|
||||||
|
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
|
.param("isbn", "isbn1")
|
||||||
|
.param("name", "name1")
|
||||||
|
.param("author", "author1");
|
||||||
|
ResultActions addBookResult = mockMvc.perform(addBookRequest);
|
||||||
|
|
||||||
|
addBookResult.andExpect(status().is3xxRedirection())
|
||||||
|
.andExpect(redirectedUrl("/book/addBook"))
|
||||||
|
.andExpect(flash().attribute("savedBook", hasProperty("isbn", equalTo("isbn1"))))
|
||||||
|
.andExpect(flash().attribute("addBookSuccess", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Collection<Book> existingBooks() {
|
||||||
|
List<Book> books = new ArrayList<>();
|
||||||
|
books.add(new Book("isbn1", "name1", "author1"));
|
||||||
|
books.add(new Book("isbn2", "name2", "author2"));
|
||||||
|
books.add(new Book("isbn3", "name3", "author3"));
|
||||||
|
return books;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.baeldung.boot.jsp.repository.impl;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||||
|
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||||
|
|
||||||
|
public class InMemoryBookRepositoryUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmtpyData_whenFindAll_thenReturnEmptyCollection() {
|
||||||
|
BookRepository bookRepository = new InMemoryBookRepository(Collections.emptyMap());
|
||||||
|
Collection<BookData> storedBooks = bookRepository.findAll();
|
||||||
|
|
||||||
|
assertEquals(0, storedBooks.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInitialData_whenFindAll_thenReturnInitialData() {
|
||||||
|
BookRepository bookRepository = new InMemoryBookRepository(initialBookData());
|
||||||
|
Collection<BookData> storedBooks = bookRepository.findAll();
|
||||||
|
|
||||||
|
assertEquals(3, storedBooks.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInitialData_whenFindUnavailableIsbn_thenReturnEmpty() {
|
||||||
|
BookRepository bookRepository = new InMemoryBookRepository(initialBookData());
|
||||||
|
Optional<BookData> storedBookOpt = bookRepository.findById("isbn4");
|
||||||
|
|
||||||
|
assertFalse(storedBookOpt.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInitialData_whenFindAvailableIsbn_thenReturnItem() {
|
||||||
|
BookRepository bookRepository = new InMemoryBookRepository(initialBookData());
|
||||||
|
Optional<BookData> storedBookOpt = bookRepository.findById("isbn1");
|
||||||
|
|
||||||
|
assertTrue(storedBookOpt.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAddedIsbn_whenFindAvailableIsbn_thenReturnItem() {
|
||||||
|
BookRepository bookRepository = new InMemoryBookRepository(Collections.emptyMap());
|
||||||
|
bookRepository.add(new BookData("isbn4", "name4", "author4"));
|
||||||
|
Optional<BookData> storedBookOpt = bookRepository.findById("isbn4");
|
||||||
|
|
||||||
|
assertTrue(storedBookOpt.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, BookData> initialBookData() {
|
||||||
|
Map<String, BookData> initData = new HashMap<>();
|
||||||
|
initData.put("isbn1", new BookData("isbn1", "name1", "author1"));
|
||||||
|
initData.put("isbn2", new BookData("isbn2", "name2", "author2"));
|
||||||
|
initData.put("isbn3", new BookData("isbn3", "name3", "author3"));
|
||||||
|
return initData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.baeldung.boot.jsp.service;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
|
||||||
|
import com.baeldung.boot.jsp.dto.Book;
|
||||||
|
import com.baeldung.boot.jsp.exception.DuplicateBookException;
|
||||||
|
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||||
|
import com.baeldung.boot.jsp.repository.impl.InMemoryBookRepository;
|
||||||
|
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||||
|
public class BookServiceIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BookService bookService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void givenNoAddedBooks_whenGetAllBooks_thenReturnInitialBooks() {
|
||||||
|
Collection<Book> storedBooks = bookService.getBooks();
|
||||||
|
|
||||||
|
assertEquals(3, storedBooks.size());
|
||||||
|
assertThat(storedBooks, hasItem(hasProperty("isbn", equalTo("ISBN-TEST-1"))));
|
||||||
|
assertThat(storedBooks, hasItem(hasProperty("isbn", equalTo("ISBN-TEST-2"))));
|
||||||
|
assertThat(storedBooks, hasItem(hasProperty("isbn", equalTo("ISBN-TEST-3"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void givenBookNotAlreadyExists_whenAddBook_thenReturnSuccessfully() {
|
||||||
|
Book bookToBeAdded = new Book("ISBN-ADD-TEST-4", "Added Book 4", "Added Book 4 Author");
|
||||||
|
Book storedBook = bookService.addBook(bookToBeAdded);
|
||||||
|
|
||||||
|
assertEquals(bookToBeAdded.getIsbn(), storedBook.getIsbn());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void givenBookAlreadyExists_whenAddBook_thenDuplicateBookException() {
|
||||||
|
Book bookToBeAdded = new Book("ISBN-ADD-TEST-4", "Updated Book 4", "Updated Book 4 Author");
|
||||||
|
|
||||||
|
assertThrows(DuplicateBookException.class, () -> bookService.addBook(bookToBeAdded));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan("com.baeldung.boot.jsp")
|
||||||
|
static class ContextConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public BookRepository provideBookRepository() {
|
||||||
|
return new InMemoryBookRepository(initialBookData());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, BookData> initialBookData() {
|
||||||
|
Map<String, BookData> initData = new HashMap<>();
|
||||||
|
initData.put("ISBN-TEST-1", new BookData("ISBN-TEST-1", "Book 1", "Book 1 Author"));
|
||||||
|
initData.put("ISBN-TEST-2", new BookData("ISBN-TEST-2", "Book 2", "Book 2 Author"));
|
||||||
|
initData.put("ISBN-TEST-3", new BookData("ISBN-TEST-3", "Book 3", "Book 3 Author"));
|
||||||
|
return initData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.baeldung.boot.jsp.service.impl;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.AdditionalAnswers;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import com.baeldung.boot.jsp.dto.Book;
|
||||||
|
import com.baeldung.boot.jsp.exception.DuplicateBookException;
|
||||||
|
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||||
|
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||||
|
import com.baeldung.boot.jsp.service.BookService;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class BookServiceImplUnitTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BookRepository bookRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetBooks_thenAllBooksReturned() {
|
||||||
|
when(bookRepository.findAll()).thenReturn(existingBooks());
|
||||||
|
BookService bookService = new BookServiceImpl(bookRepository);
|
||||||
|
|
||||||
|
Collection<Book> storedBooks = bookService.getBooks();
|
||||||
|
assertEquals(3, storedBooks.size());
|
||||||
|
assertThat(storedBooks, hasItem(hasProperty("isbn", equalTo("isbn1"))));
|
||||||
|
assertThat(storedBooks, hasItem(hasProperty("isbn", equalTo("isbn2"))));
|
||||||
|
assertThat(storedBooks, hasItem(hasProperty("isbn", equalTo("isbn3"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddBook_thenAddSuccessful() {
|
||||||
|
when(bookRepository.findById(anyString())).thenReturn(Optional.empty());
|
||||||
|
when(bookRepository.add(any(BookData.class))).thenAnswer(AdditionalAnswers.returnsFirstArg());
|
||||||
|
BookService bookService = new BookServiceImpl(bookRepository);
|
||||||
|
Book book = bookService.addBook(new Book("isbn1", "name1", "author1"));
|
||||||
|
|
||||||
|
assertEquals("isbn1", book.getIsbn());
|
||||||
|
assertEquals("name1", book.getName());
|
||||||
|
assertEquals("author1", book.getAuthor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBookAlreadyExist_whenAddBook_thenDuplicateBookException() {
|
||||||
|
BookData existingBook = new BookData("isbn1", "name1", "author1");
|
||||||
|
when(bookRepository.findById("isbn1")).thenReturn(Optional.of(existingBook));
|
||||||
|
BookService bookService = new BookServiceImpl(bookRepository);
|
||||||
|
Book bookToBeAdded = new Book("isbn1", "name1", "author1");
|
||||||
|
|
||||||
|
assertThrows(DuplicateBookException.class, () -> bookService.addBook(bookToBeAdded));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Collection<BookData> existingBooks() {
|
||||||
|
List<BookData> books = new ArrayList<>();
|
||||||
|
books.add(new BookData("isbn1", "name1", "author1"));
|
||||||
|
books.add(new BookData("isbn2", "name2", "author2"));
|
||||||
|
books.add(new BookData("isbn3", "name3", "author3"));
|
||||||
|
return books;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue