We have model like this:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.pluralsight.bookstore.model; 2 3 import javax.persistence.*; 4 import java.util.Date; 5 6 /** 7 * @author Antonio Goncalves 8 * http://www.antoniogoncalves.org 9 * -- 10 */ 11 12 @Entity 13 public class Book { 14 15 // ====================================== 16 // = Attributes = 17 // ====================================== 18 19 @Id 20 @GeneratedValue 21 private Long id; 22 23 @Column(length = 200) 24 private String title; 25 26 @Column(length = 10000) 27 private String description; 28 29 @Column(name = "unit_cost") 30 private Float unitCost; 31 32 @Column(length = 50) 33 private String isbn; 34 35 @Column(name = "publication_date") 36 @Temporal(TemporalType.DATE) 37 private Date publicationDate; 38 39 @Column(name = "nb_of_pages") 40 private Integer nbOfPages; 41 42 @Column(name = "image_url") 43 private String imageURL; 44 45 @Enumerated 46 private com.pluralsight.bookstore.model.Language language; 47 48 // ====================================== 49 // = Constructors = 50 // ====================================== 51 52 public Book() { 53 } 54 55 public Book(String isbn, String title, Float unitCost, Integer nbOfPages, com.pluralsight.bookstore.model.Language language, Date publicationDate, String imageURL, String description) { 56 this.isbn = isbn; 57 this.title = title; 58 this.unitCost = unitCost; 59 this.nbOfPages = nbOfPages; 60 this.language = language; 61 this.publicationDate = publicationDate; 62 this.imageURL = imageURL; 63 this.description = description; 64 } 65 66 // ====================================== 67 // = Getters and Setters = 68 // ====================================== 69 70 71 public Long getId() { 72 return id; 73 } 74 75 public void setId(Long id) { 76 this.id = id; 77 } 78 79 public String getTitle() { 80 return title; 81 } 82 83 public void setTitle(String title) { 84 this.title = title; 85 } 86 87 public String getDescription() { 88 return description; 89 } 90 91 public void setDescription(String description) { 92 this.description = description; 93 } 94 95 public Float getUnitCost() { 96 return unitCost; 97 } 98 99 public void setUnitCost(Float unitCost) { 100 this.unitCost = unitCost; 101 } 102 103 public String getIsbn() { 104 return isbn; 105 } 106 107 public void setIsbn(String isbn) { 108 this.isbn = isbn; 109 } 110 111 public Date getPublicationDate() { 112 return publicationDate; 113 } 114 115 public void setPublicationDate(Date publicationDate) { 116 this.publicationDate = publicationDate; 117 } 118 119 public com.pluralsight.bookstore.model.Language getLanguage() { 120 return language; 121 } 122 123 public void setLanguage(Language language) { 124 this.language = language; 125 } 126 127 public Integer getNbOfPages() { 128 return nbOfPages; 129 } 130 131 public void setNbOfPages(Integer nbOfPages) { 132 this.nbOfPages = nbOfPages; 133 } 134 135 public String getImageURL() { 136 return imageURL; 137 } 138 139 public void setImageURL(String imagURL) { 140 this.imageURL = imagURL; 141 } 142 143 // ====================================== 144 // = Methods hash, equals, toString = 145 // ====================================== 146 147 @Override 148 public String toString() { 149 return "Book{" + 150 "id=" + id + 151 ", title='" + title + '\'' + 152 ", description='" + description + '\'' + 153 ", unitCost=" + unitCost + 154 ", isbn='" + isbn + '\'' + 155 ", publicationDate=" + publicationDate + 156 ", language=" + language + 157 '}'; 158 } 159 }
We have Resposity like this:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.pluralsight.bookstore.repository; 2 3 import com.pluralsight.bookstore.model.Book; 4 5 import javax.persistence.EntityManager; 6 import javax.persistence.PersistenceContext; 7 import javax.persistence.TypedQuery; 8 import javax.transaction.Transactional; 9 import java.util.List; 10 11 import static javax.transaction.Transactional.TxType.REQUIRED; 12 import static javax.transaction.Transactional.TxType.SUPPORTS; 13 14 15 /** 16 * @author Antonio Goncalves 17 * http://www.antoniogoncalves.org 18 * -- 19 */ 20 21 // For readonly methods we want to using SUPPORTS 22 @Transactional(SUPPORTS) 23 public class BookRepository { 24 25 // ====================================== 26 // = Injection Points = 27 // ====================================== 28 29 @PersistenceContext(unitName = "bookStorePU") 30 private EntityManager em; 31 32 // ====================================== 33 // = Business methods = 34 // ====================================== 35 36 public Book find(Long id) { 37 return em.find(Book.class, id); 38 } 39 40 public List<Book> findAll() { 41 // For complex SQL, we can also using Query language 42 TypedQuery<Book> query = em.createQuery("SELECT b FROM Book b ORDER BY b.title DESC", Book.class); 43 return query.getResultList(); 44 } 45 46 public Long countAll() { 47 TypedQuery<Long> query = em.createQuery("SELECT COUNT(b) FROM Book b", Long.class); 48 return query.getSingleResult(); 49 } 50 51 // For creating and deleting methods, we want to use REQUIRED 52 @Transactional(REQUIRED) 53 public Book create(Book book) { 54 em.persist(book); 55 return book; 56 } 57 58 @Transactional(REQUIRED) 59 public void delete(Long id) { 60 em.remove(em.getReference(Book.class, id)); 61 } 62 }
We want to create a integration test for BookResposity:
package com.pluralsight.bookstore.repository; import com.pluralsight.bookstore.model.Book; import com.pluralsight.bookstore.model.Language; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; import javax.inject.Inject; import java.util.Date; import static org.junit.Assert.*; @RunWith(Arquillian.class) public class BookRepositoryTest { @Inject private BookRepository bookRepository; @Test public void create() throws Exception { // Test counting books assertEquals(Long.valueOf(0), bookRepository.countAll()); assertEquals(0, bookRepository.findAll().size()); // Create book Book book = new Book("isbn", "title", 12F, 123, Language.ENGLISH, new Date(), "imageURL", "description"); book = bookRepository.create(book); Long bookId = book.getId(); assertNotNull(bookId); // Find created book Book bookFound = bookRepository.find(bookId); assertEquals("title", bookFound.getTitle()); assertEquals(1, bookRepository.findAll().size()); // Delete the book bookRepository.delete(bookId); assertEquals(Long.valueOf(0), bookRepository.countAll()); assertEquals(0, bookRepository.findAll().size()); } @Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(BookRepository.class) .addClass(Book.class) .addClass(Language.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") .addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml"); } @org.junit.Test public void create() { } }
@Deployment is part of test configuration, here we need to add all the dependices and test persistence.xml file.
@Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(BookRepository.class) .addClass(Book.class) .addClass(Language.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") .addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml"); }