2015-08-31 13 views
3

我的構建器設置爲處理參數或屬性。這可能會改變未來,但現在這是我在我的建設者:在AutoFixture ISpecimenBuilder中使用RegEx時,爲什麼總是返回相同的值?

public class UserNameBuilder : ISpecimenBuilder 
{ 
    public object Create(object request, ISpecimenContext context) 
    { 
     var propertyInfo = request as PropertyInfo; 
     if (propertyInfo != null && propertyInfo.Name == "UserName" && propertyInfo.PropertyType == typeof(string)) 
     { 
      return GetUserName(); 
     } 

     var parameterInfo = request as ParameterInfo; 
     if (parameterInfo != null && parameterInfo.Name == "userName" && parameterInfo.ParameterType == typeof(string)) 
     { 
      return GetUserName(); 
     } 

     return new NoSpecimen(request); 
    } 

    static object GetUserName() 
    { 
     var fixture = new Fixture(); 
     return new SpecimenContext(fixture).Resolve(new RegularExpressionRequest(@"^[a-zA-Z0-9_.]{6,30}$")); 
    } 
} 

我的用戶名對象是值類型對象,如下所示:

public class UserName : SemanticType<string> 
{ 
    private static readonly Regex ValidPattern = new Regex(@"^[a-zA-Z0-9_.]{6,30}$"); 

    public UserName(string userName) : base(IsValid, userName) 
    { 
     Guard.NotNull(() => userName, userName); 
     Guard.IsValid(() => userName, userName, IsValid, "Invalid username"); 
    } 

    public static bool IsValid(string candidate) 
    { 
     return ValidPattern.IsMatch(candidate); 
    } 

    public static bool TryParse(string candidate, out UserName userName) 
    { 
     userName = null; 

     try 
     { 
      userName = new UserName(candidate); 
      return true; 
     } 
     catch (ArgumentException ex) 
     { 
      return false; 
     } 
    } 
} 

用戶名類繼承自SemanticType是爲我的值類型提供基礎的項目。

每當我使用AutoFixture如下:

var fixture = new Fixture(); 
fixture.Customizations.Add(new UserNameBuilder()); 

var userName = fixture.Create<UserName>(); 

我總是得到值「......」我想每一次我會得到不同的值。我看到預期的行爲?

+0

你用調試器來逐步通過它? – sln

+0

在我的代碼中,是的,但沒有在AutoFixture源代碼中 – TortillaCurtain

回答

3

如果可能的話,favor negated character classes instead of the dot,並嘗試use the dot sparingly

^([a-zA-Z0-9]|[._](?![.])){6,30}$ 

Regular expression visualization

上述正則表達式匹配也得到由最初的一個問題提供,例如匹配的文本nik_s.bax_vanis

這也使得AutoFixture產生不同的文本以及(原諒我的F#):

// PM> Install-Package Unquote 
// PM> Install-Package AutoFixture 
// PM> Install-Package FsCheck.Xunit 

open FsCheck 
open FsCheck.Xunit 
open Ploeh.AutoFixture 
open Ploeh.AutoFixture.Kernel 
open Swensen.Unquote 

[<Property>] 
let ``Generated strings from RegEx are not all the same`` (PositiveInt count) = 
    let fixture = new Fixture() 
    let context = new SpecimenContext(fixture) 

    let results = seq { 
     for i in 1 .. count do 
      yield context.Resolve(
       new RegularExpressionRequest("^([a-zA-Z0-9]|[._](?![.])){6,30}$")) } 

    let threshold = count/10 
    results |> Seq.distinct |> Seq.length >! threshold 

原正則表達式是罰款。 - 這是引擎是重複dot多次地:

^[a-zA-Z0-9_.]{6,30}$ 

Regular expression visualization

+0

感謝@Nikos,新的RegEx模式是一個很大的幫助。首先,我只是簡單地用舊模式替代新模式。我確實得到的結果與以前不同,即我不再收到6個點的字符串。但是,我的代碼循環50次以生成50個假數據庫記錄,而且我仍然從我的構建器獲取重複結果。這是因爲我的代碼與你寫的是什麼?我對F#不熟悉,所以我沒有翻譯它。 – TortillaCurtain

+0

當您嘗試生成與給定的正則表達式匹配的文本時,您可能會*隨着時間的推移獲得相同的結果。 –

+1

生成與給定正則表達式匹配的50個唯一字符串的一種方法是使用您的問題中顯示的「ISpecimenBuilder」與測試代碼中的「Generator 」組合。 –

相關問題