我們在寫程式中,絕對會需要撰寫測試,而很多測試情境需要使用假資料。
以下是一個 People
類別以及兩個 enum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class People { public string Id { get; set; }
public string Name { get; set; }
public string EMail { get; set; }
public int Age { get; set; }
public int Height { get; set; }
public decimal TotalAssets { get; set; }
public Gender Gender { get; set; }
public SexualOrientation SexualOrientation { get; set; } }
public enum Gender { Male = 0, Female = 1 }
public enum SexualOrientation { Heterosexual = 0, Homosexual = 1, Bisexual = 2 }
|
以往我們都是這樣產生假資料的…
1 2 3 4 5 6 7 8 9 10 11
| var mysterious = new People { Id = "Y000000001", Name = "MidSquare", EMail = "[email protected]", Age = 143, Height = 170, TotalAssets = 999999999999M, Gender = Gender.Male, SexualOrientation = SexualOrientation.Heterosexual };
|
要隨機性的話就會開始使用 random 的方式,但會有一些問題
- 資料不夠隨機
- 各種類別的屬性都必須個別刻出隨機的方法
- CODE 很多
- 產生假資料很難客製化條件
今天要介紹的是 Bogus,是 DotNet 的產生假資料工具,其功能與類型真的是廣泛到不可思議,有興趣的可以去看看他的 Github
首先透過 nuget 安裝 Bogus,接著程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| People[] GeneratePeopleViaBogus(int generateCount = 1) { return new Faker<People>() .StrictMode(true) .RuleFor(p => p.Id, f => $"{f.Random.Char('A', 'Z') + f.Random.Int(1, 999999999)}") .RuleFor(p => p.Name, f => f.Name.FullName()) .RuleFor(p => p.EMail, f => f.Person.Email) .RuleFor(p => p.Age, f => f.Random.Int(0, 120)) .RuleFor(p => p.Height, f => f.Random.Int(20, 300)) .RuleFor(p => p.TotalAssets, f => f.Finance.Amount(0, 9999999M)) .RuleFor(p => p.Gender, f => f.PickRandom<Gender>()) .RuleFor(p => p.SexualOrientation, f => f.PickRandomWithout(SexualOrientation.Bisexual)) .Generate(generateCount) .ToArray(); }
var person = GeneratePeopleViaBogus().First(); var people = GeneratePeopleViaBogus(10);
|
可以看到上方程式,我能單獨產生一筆假資料,也能夠一次產生十筆。
特別注意項目
.StrictMode(true)
:我強烈建議大家要使用嚴格模式,這個模式是強制規定每個屬性都要建立規則以產生假資料。首先是新增一個屬性,忘記改這個測試就會直接中測試錯誤,硬性提醒你修改到相關功能,需調整測試; 其次是完整比較測試的物件是有絕對好處的,避免某些預期結果沒被測到。
PickRandom<Gender>
隨機產生這個 enum 底下的值
PickRandomWithout(SexualOrientation.Bisexual)
隨機產生這個 enum 底下的值,除了指定的不要的項目
.Generate(generateCount)
一次產生幾筆資料
產生資料後的邏輯
Bogus 也考量到有些邏輯是仰賴產生資料後的,可以使用 FinishWith
語法。
這次我們保留了新增的 Remark
欄位,先不給予任何假資料,而是透過 TotalAssets
隨機值來設定:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| People[] GeneratePeopleViaBogus(int generateCount = 1) { return new Faker<People>() .StrictMode(true) .RuleFor(p => p.TotalAssets, f => f.Finance.Amount(0, 9999999M)) .RuleFor(p => p.Remark, "") .FinishWith((f, d) => { d.Remark = d.TotalAssets > 10000000m ? "I am rich" : "I am poor"; }) .Generate(generateCount) .ToArray(); }
|
Bogus 這個工具非常好用,還有很多產生各類資料的方法,可以去爬爬 Bogus Github。
只要寫足夠多的測試,絕對很有機會測出程式碼的盲點,同理,寫出來的測試也有非常多盲點XD