.net測試篇之測試神器Autofixture基本配置一

系列目錄html

實際工做中咱們須要的數據邏輯萬千,變幻無窮,而AutoFixture默認是按照必定算法隨機生成一些假數據,雖然這在多數時候是ok的,可是可能不能知足咱們的全部業務場景,有些時候咱們須要進行一些配置,以期達到指定目標.算法

AutoFixture簡單使用

前面我介首先介紹的是AutoFixture如何與Nunit結合提供測試數據,這裏咱們介紹一下它自身,即脫離Nunit時它是如何工做起來的.服務器

這裏主要用到的就是Fixture對象的Create 泛型方法 框架

看如下代碼dom

[Test]     
        public void FixValueTest()
        {
            var fix = new Fixture();
            var str = fix.Create<string>();
        }

經過以上代碼,咱們就可能建立一個string類型的對象,其它對象也是如法炮製.函數

下面咱們來解決上一節中遺漏的一個問題,就是如何在建立集合的時候顯式的指定個數.測試

其實也很簡單,那就是在建立Fixture對象的時候指定一個RepeatCount,這樣就能夠生成指定數量的集合啦.ui

代碼改成以下code

[Test]     
        public void FixValueTest()
        {
            var fix = new Fixture {RepeatCount = 10};
            var str = fix.Create<IEnumerable<string>>();

        }

就能夠生成一個包含10個String元素的集合.htm

不少時候咱們並非簡單的建立一個字符串或者數字,而是建立一個對象,不少時候咱們要是對這些對象進行驗證的,若是隨機生成一些可能沒法經過驗證,咱們下面介紹如何按照必定的規則生成一個對象.

好比說咱們要生成一個Person對象,服務器對Person的Name是要約束的,不能包含特定符號和阿拉伯數字,而AutoFixture自動生成的則是Guid轉成的字符字符串,而且長度也不符合姓名規則.

下面咱們看一下如何生成一個例規的姓名.

[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是咱們自定義的,它實現了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咱們剛纔用到過,這裏把它移到這裏來.

咱們來分析下這段代碼,構造函數裏咱們接收一個int類型變量,用於自定義生成字符串的長度.
下面的Create方法爲從接口裏實現來的方法.
它的第一個參數request爲要建立的對象,對於咱們的Person類來講,它要建立這個類和類裏的全部屬性,每個屬性都是一個request對象.下面的代碼咱們判斷請求對象是不是屬性,若是是而且屬性名是Name而且屬性類型爲string,那麼咱們就返回算法獲得的值,不然返回NoSpecimen,返回NoSpecimen表示不使用自定義的算法.

經過以上配置生成的name就能符合咱們的需求了.

[info]在集成測試過程當中咱們還能夠對省市縣等數據創建起列表,而後動態自定義填充.

以上咱們判斷屬性名是不是Name條件過嚴,咱們能夠適當放寬一些,則能適應的場景更廣.

相關文章
相關標籤/搜索