系列目錄 <https://www.cnblogs.com/tylerzhou/p/11386635.html>
實際工作中我們需要的數(shù)據(jù)邏輯萬千,千變萬化,而AutoFixture默認是按照一定算法隨機生成一些假數(shù)據(jù),雖然這在多數(shù)時候是ok的,但是可能不能滿足我們的所有業(yè)務場景,有些時候我們需要進行一些配置,以期達到指定目標.
AutoFixture簡單使用
前面我介首先介紹的是AutoFixture如何與Nunit結合提供測試數(shù)據(jù),這里我們介紹一下它自身,即脫離Nunit時它是如何工作起來的.
這里主要用到的就是Fixture對象的Create泛型方法
看以下代碼
[Test] public void FixValueTest() { var fix = new Fixture(); var str =
fix.Create<string>(); }
通過以上代碼,我們就可能創(chuàng)建一個string類型的對象,其它對象也是如法炮制.
下面我們來解決上一節(jié)中遺漏的一個問題,就是如何在創(chuàng)建集合的時候顯式的指定個數(shù).
其實也很簡單,那就是在創(chuàng)建Fixture對象的時候指定一個RepeatCount,這樣就可以生成指定數(shù)量的集合啦.
代碼改為如下
[Test] public void FixValueTest() { var fix = new Fixture {RepeatCount = 10};
var str = fix.Create<IEnumerable<string>>(); }
就可以生成一個包含10個String元素的集合.
很多時候我們并不是簡單的創(chuàng)建一個字符串或者數(shù)字,而是創(chuàng)建一個對象,很多時候我們要是對這些對象進行驗證的,如果隨機生成一些可能無法通過驗證,我們下面介紹如何按照一定的規(guī)則生成一個對象.
比如說我們要生成一個Person對象,服務器對Person的Name是要約束的,不能包含特定符號和阿拉伯數(shù)字,而AutoFixture自動生成的則是Guid轉成的字符字符串,并且長度也不符合姓名規(guī)則.
下面我們看一下如何生成一個例規(guī)的姓名.
[Test] public void FixValueTest() { var s = GetString(5); var fix = new
Fixture(); fix.Customizations.Add(new StringGenerator(() => s)); var person=
fix.Create<Person>(); } string GetString(int count) { List<int> ints = new
List<int>(); Random rand = new Random(); for (int i = 0; i < count; i++) { int
value = rand.Next(97 ,122); ints.Add(value); } var charArr =
ints.Select(Convert.ToChar).ToArray(); var str = string.Concat(charArr); return
str; }
這里我們自定義了一個算法,生成一個字符串,然后在fix配置里的自定義配置里面添加一個StringGenerator自定義配置類(這個類是框架帶的),它接收一個委托.這樣我們就可以得到期待的字符串了.
我們把測試代碼改為如下
[Test] public void FixValueTest() { var fix = new Fixture();
fix.Customizations.Add(new StringSpecimenBuilder()); var person=
fix.Create<Person>(); }
這里的StringSpecimenBuilder是我們自定義的,它實現(xiàn)了ISpecimenBuilder接口,我們看下代碼
public class StringSpecimenBuilder:ISpecimenBuilder { private readonly int
_strLenCount; public StringSpecimenBuilder(int strLenCount=5) { _strLenCount =
strLenCount; } public object Create(object request, ISpecimenContext context) {
var property = request as PropertyInfo; if (property != null && property.Name
== "Name" && property.PropertyType == typeof(string)) return
GetString(_strLenCount); return new NoSpecimen(); } string GetString(int count)
{ List<int> ints = new List<int>(); Random rand = new Random(); for (int i = 0;
i < count; i++) { int value = rand.Next(97, 122); ints.Add(value); } var
charArr = ints.Select(Convert.ToChar).ToArray(); var str =
string.Concat(charArr); return str; } }
其中的GetString我們剛才用到過,這里把它移到這里來.
我們來分析下這段代碼,構造函數(shù)里我們接收一個int類型變量,用于自定義生成字符串的長度.
下面的Create方法為從接口里實現(xiàn)來的方法.
它的第一個參數(shù)request為要創(chuàng)建的對象,對于我們的Person類來說,它要創(chuàng)建這個類和類里的所有屬性,每一個屬性都是一個request對象.下面的代碼我們判斷請求對象是否是屬性,如果是并且屬性名是Name并且屬性類型為string,那么我們就返回算法得到的值,否則返回NoSpecimen,返回NoSpecimen表示不使用自定義的算法.
通過以上配置生成的name就能符合我們的需求了.
[info]在集成測試過程中我們還可以對省市縣等數(shù)據(jù)建立起列表,然后動態(tài)自定義填充.
以上我們判斷屬性名是否是Name條件過嚴,我們可以適當放寬一些,則能適應的場景更廣.
熱門工具 換一換