2016-04-01 57 views
3

我正在寫一些單元測試,並有一個叫做Account類具有AutoFixture,創建電子郵件地址列表

public Guid AccountId {get;set;} 
public IEnumerable<string> EmailAddresses {get;set;} 
etc... 

我想用autofixture以創建帳戶,但我有麻煩電子郵件格式。

我已經試過

fixture.Register<string>(() => string.Format("{0}@acme.com", fixture.Create<string>())); 

但導致循環問題。

我能做到這一點

fixture.Register<string>(() => string.Format("{0}@acme.com", fixture.Create<int>())); 

但我寧願在地址開始的字符串。

編輯 多虧了兩個答案我有一個書面了總結和一些其他情況如下後 - http://nodogmablog.bryanhogan.net/2016/04/customizing-a-specific-string-inside-a-class-using-autofixture/

回答

7

有幾個這樣做的方式。這裏是其中的一個:

假設MyClass被定義爲

public class MyClass 
{ 
    public Guid AccountId { get; set; } 
    public IEnumerable<string> EmailAddresses { get; set; } 
} 

然後,Fixture對象可定製像這樣

var fixture = new Fixture(); 
fixture.Customize<MyClass>(c => c 
    .With(x => 
     x.EmailAddresses, 
     fixture.CreateMany<MailAddress>().Select(x => x.ToString()))); 

var result = fixture.Create<MyClass>(); 

這樣一來,EmailAddresses將充滿電子郵件字符串看起來像:

"[email protected]" 
"[email protected]" 
"[email protected]" 
+0

你不想'選擇(X => x.Address)'? ToString在一個郵件地址上產生''ecfd3086-48c7-4999-8b5e-c19f9d0875ff「<[email protected]>'' –

3

這是其中之一AutoFixture在你的對象模型的可用性方面給你反饋的情況。

如果EmailAddresses屬性應該只包含有效的電子郵件地址,那麼您應該問自己,將它們表示爲通用字符串是the right choice。類似MailAddress類的更具體類型將限制該屬性的有效值集。 由於AutoFixture知道如何創建MailAddress的實例,因此它還可以更輕鬆地爲其生成測試數據。

話雖如此,如果它是不可行的,你要改變的對象模型,你仍然可以寫一個customization告訴AutoFixture提供IEnumerable<string>類型的任何屬性或參數有效的電子郵件地址與email在他們的名字的地方:

public class EmailAddressStringsGenerator : ISpecimenBuilder 
{ 
    public object Create(object request, ISpecimenContext context) 
    { 
     if (IsEnumerableOfStringPropertyOrParameterNamedEmail(request)) 
     { 
      return CreateManyEmailAddresses(context); 
     } 

     return new NoSpecimen(); 
    } 

    static bool IsEnumerableOfStringPropertyOrParameterNamedEmail(object request) 
    { 
     return IsEnumerableOfStringPropertyNamedEmail(request) || 
       IsEnumerableOfStringParameterNamedEmail(request); 
    } 

    static bool IsEnumerableOfStringPropertyNamedEmail(object request) 
    { 
     var property = request as PropertyInfo; 
     return property != null && 
       property.Name.ContainsIgnoringCase("email") && 
       typeof(IEnumerable<string>).IsAssignableFrom(property.PropertyType); 
    } 

    static bool IsEnumerableOfStringParameterNamedEmail(object request) 
    { 
     var parameter = request as ParameterInfo; 
     return parameter != null && 
       parameter.Name.ContainsIgnoringCase("email") && 
       typeof(IEnumerable<string>).IsAssignableFrom(parameter.ParameterType); 
    } 

    static IEnumerable<string> CreateManyEmailAddresses(ISpecimenContext context) 
    { 
     var addresses = (IEnumerable<MailAddress>) 
      context.Resolve(typeof(IEnumerable<MailAddress>)); 
     return addresses.Select(a => a.Address); 
    } 
} 

您可以將它添加到Customizations屬性,然後使用在Fixture是定製:

fixture.Customizations.Insert(0, new EmailAddressStringsGenerator()); 
相關問題