JavaEEã§ãTDD - JPAç·¨ - 2
ãã£ã¡ã®ç¶ãã§ãã
ç°å¢æ§ç¯ã¯ã§ããã¨æãã®ã§ãæ¬å½ã®TDDå ¥ãã¾ããã¾ã ã®äººã¯ååã®è¨äºè¦ãããgithubããã§ãããã®ããè½ã¨ãã¦ãã ããã
1. è¨äºã®æ稿ããããï¼
ã¾ãã¯ãè¨äºã®æ稿æ©è½ãå®è£ ãã¾ããç¾å¨ãArticleã«ã¯Idããåå¨ããªãã®ã§ãã¿ã¤ãã«ã¨ã³ã³ãã³ãã追å ãã¾ããä¿®æ£ç®æã¯ãããªæãã
次ã«ãArticleFacadeTestã«ä¸è¨ã®ããã«ãã¹ãã追å ãã¾ãã
@Test public void save_and_select_Test() throws Exception { utx.begin(); // init and check. assertThat(articleFacade.count(), is(0)); // action. articleFacade.create(new Article(null, "title1", "contents1")); assertThat(articleFacade.count(), is(1)); articleFacade.create(new Article(null, "title2", "contents2")); assertThat(articleFacade.count(), is(2)); // expected. List articles = simpleSort(articleFacade.findAll(), "Title"); assertThat(articles.size(), is(2)); assertThat(articles.get(0).getTitle(), is("title1")); assertThat(articles.get(0).getContents(), is("contents1")); assertThat(articles.get(1).getTitle(), is("title2")); assertThat(articles.get(1).getContents(), is("contents2")); utx.commit(); }
è¨äºã®ä¿åã¨åé¤ã確èªãã¦ãã¾ããsimpleSortã¨ããã®ã¯è¦ªã¯ã©ã¹ã«å®ç¾©ãã¦ãã¡ã½ããã§ããRDBã¯order byããããªãéããåå¾é åºãä¿è¨¼ãããªãã®ã§ãã¹ããæ¸ãã¥ããã¨ããåé¡ãããã¾ãããªã®ã§ãåå¾ããListã第äºå¼æ°ã§sortããã®ãsimpleSortã¡ã½ããã«ãªãã¾ãã軽ãæ¸ããããã«ãªãã¬ã¯ã·ã§ã³ã¨ã使ã£ã¦ãã®ã§ãã¼ã¿éãå¢ããã¨çµæ§å¾®å¦ãªã³ã¼ãããã§ããã¾ããTDDã§ã¯ãããªã«ãã¼ã¿ä½¿ããªãã¯ããªã®ã§OK, OK.
ãã¨ãããã ãã ã¨ãä½åº¦ããã¹ãããã¨çµæãå¤ãã£ã¦ãã¾ãã®ã§ãä¸è¨ã®åæåã³ã¼ãã追å ãã¾ãã
@Before public void preparePersistenceTest() throws Exception { clearData(Article.class); }
clearDataã¯è¦ªã¯ã©ã¹ã®AbstractJPATestã«å®ç¾©ãã¦ããã¡ã½ããã§ããæå®ããEntityã¯ã©ã¹ã®ãã¼ãã«ãåé¤ãã¾ããBeforeã§æå®ãã¦ããã®ã§ãããã§ãã¹ãæ¯ã«ã¯ãªã¼ã³ãªç¶æ ã§åä½ç¢ºèªãã§ãã¾ãã ãããã®ã³ã¼ãã追å ãã¦ããã¹ããå®è¡ãã¦ã¿ã¾ããããGreenã«ãªãã°OKã§ãããã®è¾ºã¯JPAããã¨ããæã£ã¦ãæ©è½ãªã®ã§ãæ¬æ¥ã¯ãã¹ãä¸è¦ãªç®æã ã¨æãã¾ãã
2. è¨äºãæ´æ°ãããï¼
ä»åº¦ã¯ã¢ãããã¼ãã®ãã¹ãã§ãããããJPAã®æ©è½ã®ç¢ºèªãªã®ã§ãã¹ãã³ã¼ãã®ã¿ã®å®è£ ã¨ãªãã¾ãã
@Test public void update_Test() throws Exception { utx.begin(); // init and check. load(); List articles = simpleSort(articleFacade.findAll(), "Title"); assertThat(articles.size(), is(2)); assertThat(articles.get(0).getTitle(), is("title1")); assertThat(articles.get(1).getTitle(), is("title2")); // action articles.get(0).setTitle("title3"); articleFacade.edit(articles.get(0)); articleFacade.edit(new Article(null, "title4", "contents4")); // expected List updatedArticles = simpleSort(articleFacade.findAll(), "Title"); assertThat(updatedArticles.size(), is(3)); assertThat(updatedArticles.get(0).getTitle(), is("title2")); assertThat(updatedArticles.get(1).getTitle(), is("title3")); assertThat(updatedArticles.get(2).getTitle(), is("title4")); utx.commit(); }
ã¾ããåæãã¼ã¿ã®ç»é²ç¨ã«loadã¨ããã¡ã½ãããå®ç¾©ãã¾ãã.
private void load() throws Exception { articleFacade.create(new Article(null, "title1", "contents1")); articleFacade.create(new Article(null, "title2", "contents2")); }
ãã¡ããå®è¡ããã¨Greenã«ãªããã¨ã確èªã§ãããã¨æãã¾ãã
3. ã¿ã¤ã ã¹ã¿ã³ãã追å ãããï¼
ãã¦ãããããå°ãé¢ç½ããªã£ã¦ãã¾ããArticleã«ä½ææ¥ã¨æ´æ°æ¥ã®ï¼ã¤ã®Timestampã追å ãããã¨æãã¾ããã¾ãã¯ãArticleã«createdAtã¨updatedAtã®ï¼ã¤ã®ããããã£ã追å ãã¾ããå·®åã¯ãã¡ãã®éãã
注ç®ã¯@Temporalã¨@PrePersist, @PreUpdateã§ãã@Temporalã¯æ¥ä»ãªã©ã«æå®ããã¢ããã¼ã·ã§ã³ã§ããå¼æ°ã®å 容ã§ç²¾åº¦ãå¤æ´ãããã¨ãã§ãã¾ããPrePersistã¨PreUpdateã¯ããªã¬ã¼ã¨å¼ã°ãã¦ãããã®ã§ãååã®éããEntityã®æ´æ°ãä½æãªã©ã®ã¤ãã³ãã«åå¿ãã¦ãã®åã«å¿ ãå®è¡ãããã¡ã½ãããå®ç¾©ãããã¨ãã§ãã¾ãã
ã¤ãã³ãããªãã³ã§ãããå¦çãæ¸ããã®ã¯ä¸ã 便å©ã§ããã¹ãã¢ã使ãã¾ã§ããªãã¨ãã«ã¯ç¹ã«ãä»åã¯ããã§ãã¿ã¤ã ã¹ã¿ã³ãã®æ´æ°ãããã¦ãã¾ãã
ã§ã¯ããã®åä½ã確èªãã¾ãããã
@Test public void update_timestamp_Test() throws Exception { utx.begin(); // init and check. load(); List articles = simpleSort(articleFacade.findAll(), "Id"); assertThat(articles.size(), is(2)); assertThat(articles.get(0).getCreatedAt(), is(notNullValue())); assertThat(articles.get(0).getUpdatedAt(), is(notNullValue())); Long createdAt1 = articles.get(0).getCreatedAt().getTime(); Long updatedAt1 = articles.get(0).getUpdatedAt().getTime(); Long createdAt2 = articles.get(1).getCreatedAt().getTime(); Long updatedAt2 = articles.get(1).getUpdatedAt().getTime(); // action articles.get(0).setTitle("title3"); articleFacade.edit(articles.get(0)); articleFacade.edit(new Article(null, "title4", "contents4")); // expected List updatedArticles = simpleSort(articleFacade.findAll(), "Id"); assertThat(updatedArticles.size(), is(3)); // record1 assertThat(updatedArticles.get(0).getCreatedAt().getTime(), is(createdAt1)); assertThat(updatedArticles.get(0).getUpdatedAt().getTime(), is(greaterThan(updatedAt1))); // record2 assertThat(updatedArticles.get(1).getCreatedAt().getTime(), is(createdAt2)); assertThat(updatedArticles.get(1).getUpdatedAt().getTime(), is(updatedAt2)); utx.commit(); }
ãã¡ãã§Greenã«ãªã£ãã®ã確èªã§ããã¨æãã¾ãã確èªå 容ã¯ä½ææã«ã¡ããã¨æéãå ¥ããã¨ã¨ãæ´æ°ãããã¨æ´æ°æ¥ã ããã¢ãããã¼ãããããã¨ã§ãã
ããèããããããã¯ããªã¬ã¼ã®å®è£ åã«ã¡ããã¨ãã¹ãã§èµ¤ã«ãªããã¨ã確èªããã»ããè¯ãã£ãã§ããã失æãã¾ãã次ããæ¹åãããã§ãã
4. ææ°ã®è¨äºã®ä¸è¦§ãåå¾ãããï¼
ã§ã¯ã次ã¯ææ°ã®è¨äºã®ä¸è¦§ãåå¾ããæ©è½ãå®è£ ãã¾ãããã¹ãã¯ãããªæãã§ã
@Test public void find_recent_articles_Test() throws Exception { utx.begin(); // init and check. assertThat(articleFacade.count(), is(0)); for (int i = 0; i < 100; i++) { SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd"); Article article = new Article(null, "title" + i, "contents" + i); article.setCreatedAt(df.parse("2012/04/1")); article.setUpdatedAt(df.parse*1; articleFacade.create(article); } assertThat(articleFacade.count(), is(100)); // expected. List articles = simpleSort(articleFacade.findRecently(10), "Title"); assertThat(articles.size(), is(10)); int i = 90; for (Article article : articles) { assertThat(article.getTitle(), is("title" + (i++))); } utx.commit(); }
ä»åº¦ã¯ã¡ããã¨å ã«ãã¹ããæ¸ãã¾ãããã§ã¯ãå®è¡ãã¦ã¿ã¾ãããã
ããã¼ãããç®ã ã...ãããªãããã¹ããçã£èµ¤ã ã¼ãã¨ããæãã«ã¡ããã¨Redã«ãªãã¾ããããã¾ããfindRecentlyãªãã¦ã¡ã½ããå®ç¾©ãã¦ã¾ããããããã§ã¯ãfake itãæ¸ãã¾ããã¨ããããããããªæãã«æ¸ãã¾ããã
ãã¦ãæ©éå®è¡ãã¦ã¿ã¾ããGreenã§ããï¼ãã§ã¯ããã¹ãã追å ãã¾ãããã
List articles20 = simpleSort(articleFacade.findRecently(20), "Title"); assertThat(articles20.size(), is(20)); int j = 80; for (Article article : articles20) { assertThat(article.getTitle(), is("title" + (j++))); }
ãããå®è¡ããã¨ãã¡ããã¨ãã¹ãã赤ããªãã®ã確èªã§ããã¨æãã¾ãã
赤ããªã£ãã®ã§ãä»åº¦ã¯æ£ããã³ã¼ããå®è£ ãã¾ããJPQLã§ãã¡ãã®ããã«å®è£ ãã¾ãããä½æ°ã«fake itããçãã§ãwww
å®è¡ããã¨ç¡äºãGreenã«ãªããã¨ã確èªåºæ¥ã¾ããã
5. ã³ã¡ã³ãã追å ãããï¼
ããã°ãæ¸ããããã£ã±ãåå¿ãã»ããã®ã§ãã³ã¡ã³ãæ©è½ãå®è£ ãã¾ãã
ã¾ãã¯ãCommentã®ã¨ã³ãã£ãã£ã¨DAOãä½æãã¾ãããããªæããã¨ããããã¯ããã©ã«ãçæã®ã¾ã¾ã§ãã
ç¶ãã¦ãã¹ãã¯ä¸è¨ã®éãã
@Test public void comment_add_Test() throws Exception { // init and check. utx.begin(); Article article = new Article(1L, "title1", "contents1"); articleFacade.create(article); Comment comment = new Comment(null, "user2", "comment2"); comment.setArticle(article); commentFacade.create(comment); utx.commit(); // expected. utx.begin(); List<>Article> articles = simpleSort(articleFacade.findAll(), "Title"); assertThat(articles.size(), is(1)); assertThat(articles.get(0).getId(), is(1L)); assertThat(articles.get(0).getTitle(), is("title1")); Comment comment2 = commentFacade.findAll().get(0); assertThat(comment2.getName(), is("user2")); assertThat(comment2.getArticleId(), is(1L)); assertThat(comment2.getArticle().getTitle(), is("title1")); assertThat(comment2.getArticle().getId(), is(1L)); utx.commit(); }
Articleã¨Commentãç»é²ãã¦1:Nã§åæ¹åãããã³ã°ãã§ãã¦ãããã確èªãã¦ãã¾ãããã¨ããã£ã¼ã«ãã¨ãç´°ããå¤ãã£ã¦ãã®ã§è©³ç´°ã¯ãã¡ããåèã«ããããå®è¡ããã¨Redã«ãªãã¾ããCommentã«articleãç¡ãã®ã§å½ç¶ã§ããã
ã¾ãã¯ãarticleãã£ã¼ã«ãã ã追å ãã¾ããã³ã³ãã¤ã«ã¨ã©ã¼ã¯åãã¾ããããnullãè¿ã£ã¦ãã¦ããã®ã§ããã¹ããã¾ã 失æãã¦ãã¾ããããã¯ããã£ã¼ã«ãã¯ãããã®ã®ããããã³ã°ãæ£ããè¡ããã¦ããªãããã§ãã
ã¤ã¥ãã¦ã@ManyToOneã¨ã@OneToManyã¨ããããã³ã°ç³»ã®è¨å®ã追å ãã¾ãã追å ãããã®ã¯ãã¡ãã
ãã¡ããå®è¡ããã¨Greenã«ãªãã¾ããã¾ã ããã¾ãJPAã«æ £ãã¦ããªãã®ã§ãè¨è¿°ãé©åãã¯ã¡ãã£ã¨æªããã§ããã§ãã¾ãããã¹ããããã®ã§å¿ è¦ã«å¿ãã¦ä¿®æ£ã§ãã¾ãããããâãããã¬ã¬ã·ã¼ï¼ï¼
ã¾ã¨ã
JPAã¨Arquillianã®åå¼·ã«TDDãªæãã§é²ãã¦è¦ã¾ãããè²ã ãééã£ã¦ãã¨ããã¨ããããããããªãã®ã§ããã®è¾ºã¯ããã³ããå¾ ã¡ãã¦ããã¾ãã
ã¦ããJPAã¯ä»åãã¹ãæ¸ããªãããã©ã³ã¶ã¯ã·ã§ã³å¨ããèªåã®ç´æã¨ããªãç°ãªã£ã¦ããã¨ã«æ°ã¥ããã®ã§ãæ¬æ°ã§èª¿ã¹ã¨ããªãã¨æ»ã«ãããªæ°ããã¦ãã¾ãã...
ãã¨ãä»åã¯ç´ ã®Arquillianã使ãã¾ããããJPAã使ãå ´åã¯@aslakknutsenã«Tweetããã¦ããã£ãã®ã§ãArquillian Persistence Extensionã試ãã¦ã¿ããã¨æãã¾ãã
ãªããä»åä½æãããã®ã¯githubã«ç½®ãã¦ããã®ã§ãèªç±ã«ã©ããã
ã§ã¯ãHappy Hacking !