使用Mutability Detector对Java数据类的不变性进行单元测试
在我們所有的項目中,我們使用的數(shù)據(jù)類根據(jù)定義包含數(shù)據(jù)(字段),但不包含(業(yè)務(wù))邏輯。
根據(jù)最佳編碼實踐,數(shù)據(jù)類最好應(yīng)該是不可變的,因為不可變性意味著線程安全。 這里的主要參考是Joshua Bloch的Effective Java書籍; Yegor Bugayenko的帖子也很有趣。
不可變類具有幾個有趣的屬性:
- 它不能是子類的(即它應(yīng)該是最終的,或者應(yīng)該具有靜態(tài)工廠方法和私有構(gòu)造函數(shù))
- 所有字段均應(yīng)為私有字段(以防止直接訪問)
- 所有字段應(yīng)寫入一次(在實例創(chuàng)建時)(即,它們應(yīng)該是最終值且沒有設(shè)置方法)
- 所有可變類型(例如java.util.Date)字段都應(yīng)受到保護,以防止客戶端通過引用進行寫訪問
不變類的示例如下:
public final class ImmutableBean {private final String aStr;private final int anInt;public ImmutableBean(String aStr, int anInt) {this.aStr = aStr;this.anInt = anInt;}public String getAStr() {return aStr;}public int getAnInt() {return anInt;}}注意:在Java中很常見,有很多樣板代碼隱藏了不變性定義。
像Project Lombok這樣的庫使我們的生活更輕松,因為我們可以使用@Value批注輕松地定義一個不可變的類,如下所示:
@Valuepublic class LombokImmutableBean {String aStr;int anInt;}更具可讀性。
我們(單元)應(yīng)該測試一個類以檢查其不變性嗎?
在理想世界中,答案是否定的。
借助我們首選的IDE自動代碼生成功能或Lombok之類的庫,為類添加不變性并不難。
但是在現(xiàn)實世界中,當(dāng)我們創(chuàng)建類或稍后(或可能是團隊的初級成員)修改類時,可能會發(fā)生人為錯誤。 如果不使用final來添加新字段并且使用IDE代碼生成器生成了setter會怎樣? 該類不再是不變的。
重要的是要確保該類在整個項目生命周期中都是并且保持不變。
借助Mutability Detector,我們可以輕松創(chuàng)建一個測試來檢查類的不變性狀態(tài)。
像往常一樣,可以在Maven Central上找到Maven / Gradle依賴項。
為了測試我們的ImmutableBean,我們可以創(chuàng)建以下jUnit測試類:
import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;public class ImmutableBeanTest {@Testpublic void testClassIsImmutable() {assertImmutable(ImmutableBean.class);}}如果類不是不可變的,則測試將失敗。
例如,如果一個字段不是final且具有setter方法,則測試將失敗,并且錯誤消息的描述性非常強:
org.mutabilitydetector.unittesting.MutabilityAssertionError: Expected: it.gualtierotesta.testsolutions.general.beans.ImmutableBean to be IMMUTABLEbut: it.gualtierotesta.testsolutions.general.beans.ImmutableBean is actually NOT_IMMUTABLE Reasons:Field is not final, if shared across threads the Java Memory Model will not guarantee it is initialised before it is read. [Field: aStr, Class: it.gualtierotesta.testsolutions.general.beans.ImmutableBean]Field [aStr] can be reassigned within method [setaStr] [Field: aStr, Class: it.gualtierotesta.testsolutions.general.beans.ImmutableBean]完整的項目可以在我在GitHub上的Test Solutions畫廊項目中找到。 參見模塊常規(guī) 。
我建議的方法是使用Lombok,而不進行任何不變性測試。 如果不能使用Lombok(例如在舊項目中),請使用“可變性檢測器”聲明該類確實是不可變的。
翻譯自: https://www.javacodegeeks.com/2017/01/unit-testing-java-data-classes-immutability-mutability-detector.html
總結(jié)
以上是生活随笔為你收集整理的使用Mutability Detector对Java数据类的不变性进行单元测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 表格里负数加减快捷键(表格快捷键加减乘除
- 下一篇: 使用JavaParser从源文件中提取J