2015-08-31 4 views
3

Мой строитель настроен либо на работу с параметром, либо с помощью свойства. Это может измениться в будущем, но сейчас это то, что у меня в строитель:При использовании RegEx в AutoFixture ISpecimenBuilder, почему я всегда возвращаю то же значение?

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}$")); 
    } 
} 

Мой объект UserName является объектом ValueType и заключается в следующем:

класс
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; 
     } 
    } 
} 

UserName наследует 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 

Оригинальный Regular Expression отлично. - Это двигатель, который повторяет dot столько раз, сколько это возможно:

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

Regular expression visualization

+0

Спасибо @Nikos, новый шаблон RegEx был большой помощью. Для начала я просто заменил новый шаблон для старого шаблона. Я получаю результаты, которые отличаются от предыдущих, т. Е. Я больше не получаю строку из 6 точек. Тем не менее, мой код петли 50 раз, чтобы создать 50 поддельных записей базы данных, и я все еще получаю повторный результат от моего строителя. Это из-за моего кода и того, что вы написали? Я не знаком с F #, поэтому я не перевел его. – TortillaCurtain

+0

Вы * можете * получать те же результаты с течением времени при попытке сгенерировать текст, соответствующий данному регулярному выражению. –

+1

Одним из способов генерации 50 уникальных строк, которые соответствуют данному регулярному выражению, является использование 'ISpecimenBuilder', показанного в вашем вопросе, в сочетании с« Генератором »в вашем тестовом коде. –