截至 2020 年 11 月 15 日,Easy Random 處於維護模式。這意味著從現在開始只會解決錯誤修復(記錄支援除外,該支援將在 Java 16 發佈時發布)。目前僅支援版本 5.0.x(基於 Java 11)和版本 4.3.x(基於 Java 8)。請考慮儘早升級到這些版本之一。
Easy Random 是一個產生隨機 Java 物件的函式庫。您可以將其視為 JVM 的 ObjectMother。假設您有一個Person
類,並且您想要產生它的隨機實例,讓我們開始吧:
EasyRandom easyRandom = new EasyRandom ();
Person person = easyRandom . nextObject ( Person . class );
EasyRandom#nextObject
方法能夠產生任何給定類型的隨機實例。
java.util.Random
API 提供了 7 種產生隨機資料的方法: nextInt()
、 nextLong()
、 nextDouble()
、 nextFloat()
、 nextBytes()
、 nextBoolean()
和nextGaussian()
。如果你需要產生一個隨機String
怎麼辦?或者說你的域物件的隨機實例? Easy Random 提供了EasyRandom
API,它使用名為nextObject(Class type)
的方法擴充了java.util.Random
。此方法能夠產生任意 Java bean 的隨機實例。
EasyRandomParameters
類別是配置EasyRandom
實例的主要入口點。它允許您設定所有參數來控制隨機資料的生成方式:
EasyRandomParameters parameters = new EasyRandomParameters ()
. seed ( 123L )
. objectPoolSize ( 100 )
. randomizationDepth ( 3 )
. charset ( forName ( "UTF-8" ))
. timeRange ( nine , five )
. dateRange ( today , tomorrow )
. stringLengthRange ( 5 , 50 )
. collectionSizeRange ( 1 , 10 )
. scanClasspathForConcreteTypes ( true )
. overrideDefaultInitialization ( false )
. ignoreRandomizationErrors ( true );
EasyRandom easyRandom = new EasyRandom ( parameters );
有關這些參數的更多詳細信息,請參閱配置參數部分。
在大多數情況下,預設選項就足夠了,您可以使用EasyRandom
的預設建構子。
Easy Random 可讓您控制如何透過org.jeasy.random.api.Randomizer
介面產生隨機數據,並可使用java.util.function.Predicate
輕鬆從物件圖中排除某些欄位:
EasyRandomParameters parameters = new EasyRandomParameters ()
. randomize ( String . class , () -> "foo" )
. excludeField ( named ( "age" ). and ( ofType ( Integer . class )). and ( inClass ( Person . class )));
EasyRandom easyRandom = new EasyRandom ( parameters );
Person person = easyRandom . nextObject ( Person . class );
在前面的範例中,Easy Random 將:
String
類型的所有欄位設為foo
(使用定義為 lambda 表達式的Randomizer
)Person
中名為age
的Integer
類型欄位。 named
、 ofType
和inClass
靜態方法在org.jeasy.random.FieldPredicates
中定義,它提供了通用謂詞,您可以組合使用來準確定義要排除的欄位。名為TypePredicates
的類似類別可用於定義要從物件圖中排除的類型。您當然可以將自己的java.util.function.Predicate
與那些預先定義的謂詞結合使用。
用隨機資料填充 Java 物件乍看之下似乎很容易,除非您的域模型涉及許多相關的類別。在前面的範例中,假設Person
類型定義如下:
如果沒有Easy Random,您將編寫以下程式碼來建立Person
類別的實例:
Street street = new Street ( 12 , ( byte ) 1 , "Oxford street" );
Address address = new Address ( street , "123456" , "London" , "United Kingdom" );
Person person = new Person ( "Foo" , "Bar" , "[email protected]" , Gender . MALE , address );
如果這些類別不提供帶有參數的建構函數(可能是一些您無法更改的遺留類型),您可以編寫:
Street street = new Street ();
street . setNumber ( 12 );
street . setType (( byte ) 1 );
street . setName ( "Oxford street" );
Address address = new Address ();
address . setStreet ( street );
address . setZipCode ( "123456" );
address . setCity ( "London" );
address . setCountry ( "United Kingdom" );
Person person = new Person ();
person . setFirstName ( "Foo" );
person . setLastName ( "Bar" );
person . setEmail ( "[email protected]" );
person . setGender ( Gender . MALE );
person . setAddress ( address );
使用Easy Random,可以使用new EasyRandom().nextObject(Person.class)
產生隨機Person
物件。該庫將遞歸地填入所有物件圖。這是一個很大的區別!
有時,測試夾具對於測試邏輯來說並不重要。例如,如果我們想測試新排序演算法的結果,我們可以產生隨機輸入資料並斷言輸出已排序,而不管資料本身:
@ org . junit . Test
public void testSortAlgorithm () {
// Given
int [] ints = easyRandom . nextObject ( int []. class );
// When
int [] sortedInts = myAwesomeSortAlgo . sort ( ints );
// Then
assertThat ( sortedInts ). isSorted (); // fake assertion
}
另一個例子是測試域對象的持久性,我們可以產生一個隨機域對象,將其持久化並斷言資料庫包含相同的值:
@ org . junit . Test
public void testPersistPerson () throws Exception {
// Given
Person person = easyRandom . nextObject ( Person . class );
// When
personDao . persist ( person );
// Then
assertThat ( "person_table" ). column ( "name" ). value (). isEqualTo ( person . getName ()); // assretj db
}
Easy Random 在許多其他用例中也很有用,您可以在 wiki 中找到一個非詳盡的清單。
歡迎您透過 GitHub 上的拉取請求為該專案做出貢獻。請注意,Easy Random 處於維護模式,這意味著只會考慮錯誤修復的拉取請求。
如果您認為發現了錯誤或有任何疑問,請使用問題追蹤器。
感謝大家的貢獻!
麻省理工學院許可證。請參閱 LICENSE.txt。