Bogus - .Net 產生假資料的神級工具

我們在寫程式中,絕對會需要撰寫測試,而很多測試情境需要使用假資料。

以下是一個 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

  • 作者: MingYi Chou
  • 版權聲明: 轉載不用問,但請註明出處!本網誌均採用 BY-NC-SA 許可協議。