日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

对编写的代码进行单元测试_编写数据访问代码测试–单元测试是浪费

發(fā)布時(shí)間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对编写的代码进行单元测试_编写数据访问代码测试–单元测试是浪费 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

對(duì)編寫(xiě)的代碼進(jìn)行單元測(cè)試

幾年前,我是為我的數(shù)據(jù)訪問(wèn)代碼編寫(xiě)單元測(cè)試的那些開(kāi)發(fā)人員之一。 我正在孤立地測(cè)試所有內(nèi)容,我對(duì)自己感到非常滿意。 老實(shí)說(shuō),我認(rèn)為自己做得很好。 哦,男孩,我錯(cuò)了! 這篇博客文章描述了為什么我們不應(yīng)該為數(shù)據(jù)訪問(wèn)代碼編寫(xiě)單元測(cè)試,并解釋為什么我們應(yīng)該用集成測(cè)試代替單元測(cè)試。 讓我們開(kāi)始吧。

單元測(cè)試錯(cuò)誤問(wèn)題的答案

我們?yōu)閿?shù)據(jù)訪問(wèn)代碼編寫(xiě)測(cè)試,因?yàn)槲覀兿胫浪梢园搭A(yù)期工作。 換句話說(shuō),我們想找到這些問(wèn)題的答案:

  • 是否將正確的數(shù)據(jù)存儲(chǔ)到使用的數(shù)據(jù)庫(kù)?
  • 我們的數(shù)據(jù)庫(kù)查詢是否返回正確的數(shù)據(jù)?
  • 單元測(cè)試可以幫助我們找到想要的答案嗎? 嗯, 單元測(cè)試的最基本規(guī)則之一是單元測(cè)試不應(yīng)使用諸如數(shù)據(jù)庫(kù)之類的外部系統(tǒng) 。 此規(guī)則不適用于當(dāng)前情況,因?yàn)榇鎯?chǔ)正確信息和返回正確查詢結(jié)果的責(zé)任由我們的數(shù)據(jù)訪問(wèn)代碼和使用的數(shù)據(jù)庫(kù)劃分。 例如,當(dāng)我們的應(yīng)用程序執(zhí)行單個(gè)數(shù)據(jù)庫(kù)查詢時(shí),職責(zé)劃分如下:

    • 負(fù)責(zé)創(chuàng)建執(zhí)行的數(shù)據(jù)庫(kù)查詢的數(shù)據(jù)訪問(wèn)代碼。
    • 數(shù)據(jù)庫(kù)負(fù)責(zé)執(zhí)行數(shù)據(jù)庫(kù)查詢,并將查詢結(jié)果返回給數(shù)據(jù)訪問(wèn)代碼。

    問(wèn)題是,如果我們將數(shù)據(jù)訪問(wèn)代碼與數(shù)據(jù)庫(kù)隔離,則可以測(cè)試數(shù)據(jù)訪問(wèn)代碼是否創(chuàng)建了“正確的”查詢,但是我們無(wú)法確保所創(chuàng)建的查詢返回正確的查詢結(jié)果。 這就是為什么單元測(cè)試不能幫助我們找到想要的答案的原因

    告誡故事:Mo是問(wèn)題的一部分

    有段時(shí)間我為數(shù)據(jù)訪問(wèn)代碼編寫(xiě)了單元測(cè)試。 當(dāng)時(shí)我有兩個(gè)規(guī)則:

  • 每段代碼都必須單獨(dú)進(jìn)行測(cè)試。
  • 讓我們使用模擬。
  • 我當(dāng)時(shí)在一個(gè)使用Spring Data JPA的項(xiàng)目中工作,而動(dòng)態(tài)查詢是使用JPA條件查詢構(gòu)建的。 如果您不熟悉Spring Data JPA,則可能需要閱讀Spring Data JPA教程的第四部分,該教程解釋了如何使用Spring Data JPA創(chuàng)建JPA條件查詢 。 無(wú)論如何,我創(chuàng)建了一個(gè)規(guī)范構(gòu)建器類來(lái)構(gòu)建Specification <Person>對(duì)象。 創(chuàng)建Specification <Person>對(duì)象之后,將其轉(zhuǎn)發(fā)給我的Spring Data JPA存儲(chǔ)庫(kù),該存儲(chǔ)庫(kù)執(zhí)行查詢并返回查詢結(jié)果。 規(guī)范構(gòu)建器類的源代碼如下所示:

    import org.springframework.data.jpa.domain.Specification;import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root;public class PersonSpecifications {public static Specification<Person> lastNameIsLike(final String searchTerm) {return new Specification<Person>() {@Overridepublic Predicate toPredicate(Root<Person> personRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {String likePattern = getLikePattern(searchTerm); return cb.like(cb.lower(personRoot.<String>get(Person_.lastName)), likePattern);}private String getLikePattern(final String searchTerm) {return searchTerm.toLowerCase() + "%";}};} }

    讓我們看一下“驗(yàn)證”規(guī)范構(gòu)建器類創(chuàng)建“正確”查詢的測(cè)試代碼。 請(qǐng)記住,我是按照自己的規(guī)則編寫(xiě)該測(cè)試類的,這意味著結(jié)果應(yīng)該很棒。 PersonSpecificationsTest類的源代碼如下所示:

    import org.junit.Before; import org.junit.Test; import org.springframework.data.jpa.domain.Specification;import javax.persistence.criteria.*;import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.*;public class PersonSpecificationsTest {private static final String SEARCH_TERM = "Foo";private static final String SEARCH_TERM_LIKE_PATTERN = "foo%";private CriteriaBuilder criteriaBuilderMock;private CriteriaQuery criteriaQueryMock;private Root<Person> personRootMock;@Beforepublic void setUp() {criteriaBuilderMock = mock(CriteriaBuilder.class);criteriaQueryMock = mock(CriteriaQuery.class);personRootMock = mock(Root.class);}@Testpublic void lastNameIsLike() {Path lastNamePathMock = mock(Path.class); when(personRootMock.get(Person_.lastName)).thenReturn(lastNamePathMock);Expression lastNameToLowerExpressionMock = mock(Expression.class);when(criteriaBuilderMock.lower(lastNamePathMock)).thenReturn(lastNameToLowerExpressionMock);Predicate lastNameIsLikePredicateMock = mock(Predicate.class);when(criteriaBuilderMock.like(lastNameToLowerExpressionMock, SEARCH_TERM_LIKE_PATTERN)).thenReturn(lastNameIsLikePredicateMock);Specification<Person> actual = PersonSpecifications.lastNameIsLike(SEARCH_TERM);Predicate actualPredicate = actual.toPredicate(personRootMock, criteriaQueryMock, criteriaBuilderMock);verify(personRootMock, times(1)).get(Person_.lastName);verifyNoMoreInteractions(personRootMock);verify(criteriaBuilderMock, times(1)).lower(lastNamePathMock);verify(criteriaBuilderMock, times(1)).like(lastNameToLowerExpressionMock, SEARCH_TERM_LIKE_PATTERN);verifyNoMoreInteractions(criteriaBuilderMock);verifyZeroInteractions(criteriaQueryMock, lastNamePathMock, lastNameIsLikePredicateMock);assertEquals(lastNameIsLikePredicateMock, actualPredicate);} }

    這有道理嗎? 沒(méi)有! 我必須承認(rèn),此測(cè)試對(duì)任何人都沒(méi)有價(jià)值,應(yīng)該盡快刪除。 此測(cè)試有三個(gè)主要問(wèn)題:

    • 它不能幫助我們確保數(shù)據(jù)庫(kù)查詢返回正確的結(jié)果。
    • 很難理解并使情況更糟,它描述了查詢的構(gòu)建方式,但沒(méi)有描述查詢應(yīng)返回的內(nèi)容。
    • 這樣的測(cè)試很難編寫(xiě)和維護(hù)。

    事實(shí)是,此單元測(cè)試是不應(yīng)編寫(xiě)的測(cè)試的教科書(shū)示例。 它對(duì)我們沒(méi)有任何價(jià)值,但我們?nèi)匀槐仨毦S護(hù)它。 因此, 這是浪費(fèi)! 但是,如果我們?yōu)閿?shù)據(jù)訪問(wèn)代碼編寫(xiě)單元測(cè)試,就會(huì)發(fā)生這種情況。 我們最終得到了一個(gè)測(cè)試套件,無(wú)法測(cè)試正確的東西。

    數(shù)據(jù)訪問(wèn)測(cè)試正確完成

    我是單元測(cè)試的忠實(shí)擁護(hù)者,但是在某些情況下,它并不是工作的最佳工具。 這是其中一種情況。 數(shù)據(jù)訪問(wèn)代碼與使用的數(shù)據(jù)存儲(chǔ)有非常密切的關(guān)系。 這種關(guān)系是如此緊密,以至于沒(méi)有數(shù)據(jù)存儲(chǔ),數(shù)據(jù)訪問(wèn)代碼本身就沒(méi)有用。 這就是為什么將我們的數(shù)據(jù)訪問(wèn)代碼與二手?jǐn)?shù)據(jù)存儲(chǔ)區(qū)分開(kāi)來(lái)是沒(méi)有意義的。 解決這個(gè)問(wèn)題很簡(jiǎn)單。 如果我們要為數(shù)據(jù)訪問(wèn)代碼編寫(xiě)全面的測(cè)試,則必須將數(shù)據(jù)訪問(wèn)代碼與使用的數(shù)據(jù)存儲(chǔ)一起進(jìn)行測(cè)試。 這意味著我們必須忘記單元測(cè)試并開(kāi)始編寫(xiě)集成測(cè)試 。 我們必須了解,只有集成測(cè)試才能驗(yàn)證

    • 我們的數(shù)據(jù)訪問(wèn)代碼創(chuàng)建正確的數(shù)據(jù)庫(kù)查詢。
    • 我們的數(shù)據(jù)庫(kù)返回正確的查詢結(jié)果。

    如果您想知道如何為Spring支持的存儲(chǔ)庫(kù)編寫(xiě)集成測(cè)試,則應(yīng)該閱讀我的博客文章,標(biāo)題為Spring Data JPA教程:集成測(cè)試 。 它描述了如何為Spring Data JPA存儲(chǔ)庫(kù)編寫(xiě)集成測(cè)試。 但是,在為使用關(guān)系數(shù)據(jù)庫(kù)的任何存儲(chǔ)庫(kù)編寫(xiě)集成測(cè)試時(shí),可以使用相同的技術(shù)。 例如, 為測(cè)試“ 將jOOQ與Spring結(jié)合使用”教程中的示例應(yīng)用程序而編寫(xiě)的集成測(cè)試使用該博客文章中描述的技術(shù)。

    摘要

    這篇博客文章教會(huì)了我們兩件事:

    • 我們了解到,單元測(cè)試無(wú)法幫助我們驗(yàn)證數(shù)據(jù)訪問(wèn)代碼是否正常運(yùn)行,因?yàn)槲覀儫o(wú)法確保將正確的數(shù)據(jù)插入到數(shù)據(jù)存儲(chǔ)中或查詢返回正確的結(jié)果。
    • 我們了解到,應(yīng)該使用集成測(cè)試來(lái)測(cè)試數(shù)據(jù)訪問(wèn)代碼,因?yàn)閿?shù)據(jù)訪問(wèn)代碼和使用的數(shù)據(jù)存儲(chǔ)之間的關(guān)系是如此緊密,以至于沒(méi)有必要將它們分開(kāi)。

    只剩下一個(gè)問(wèn)題:您是否還在為數(shù)據(jù)訪問(wèn)代碼編寫(xiě)單元測(cè)試?

    翻譯自: https://www.javacodegeeks.com/2014/07/writing-tests-for-data-access-code-unit-tests-are-waste.html

    對(duì)編寫(xiě)的代碼進(jìn)行單元測(cè)試

    總結(jié)

    以上是生活随笔為你收集整理的对编写的代码进行单元测试_编写数据访问代码测试–单元测试是浪费的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。