2016-04-01 24 views
3

bazı birim testleri yazıyorum e-posta adresleri listesini oluşturmak ve var ben hesabı oluşturmak için autofixture kullanmak istiyorumAutoFixture,

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

sahiptir Account denilen bir sınıf, ama alma konusunda sorun yaşıyorum e-posta biçimi.

Ben

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

denedi ama bu dairesel probleme yol açtığı.

Bu

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

yapabileceğini Ama doğrusu adrese başlangıcında bir dize olurdu.

DÜZENLEME Ben burada bir yazı olarak bir özet ve birkaç diğer senaryoları yazdım hem cevaplar sayesinde - http://nodogmablog.bryanhogan.net/2016/04/customizing-a-specific-string-inside-a-class-using-autofixture/

cevap

7

Bunu yapmanın birkaç yolu vardır. İşte onlardan biri: MyClass

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

olarak tanımlanır

varsayarsak o, bir Fixture nesne böylece

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>(); 

gibi özelleştirilebilir Ve böylece EmailAddresses eposta dizeleri ile dolu olacağı benzen:

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

? Bir posta adresindeki ToString, "ecfd3086-48c7-4999-8b5e-c19f9d0875ff" ile sonuçlanır: <[email protected]> –

3

Bu bir AutoFixture'ın, nesne modelinizin kullanılabilirliğine ilişkin geribildirim verdiği durumlar.

EmailAddresses özelliğinin yalnızca geçerli e-posta adresleri içerdiği varsayılırsa, kendilerine genel dizeler olarak temsil etmenin kendilerine sorun olup olmadığını sormalısınız (the right choice). MailAddress sınıfı gibi daha spesifik bir tür, söz konusu özellik için geçerli değerler kümesini kısıtlar.Aynı zamanda, AutoFixture, MailAddress örneklerinin nasıl oluşturulacağını bildiğinden, bunun için test verilerini oluşturmayı da kolaylaştırır.

Eğer nesne modelini değiştirmek için, hala bir yerlerde kendi adlarına email ile tip IEnumerable<string> herhangi mülkiyet veya parametre için geçerli e-posta adresleri sağlamak için AutoFixture söyleyen bir customization yazabilir mümkün değilse, söyledikten:

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

ardından Customizations özelliğine ekleyerek bir Fixture bu özelleştirmeyi kullanabilirsiniz: `seç (x => x.Address)` istemiyor musunuz

fixture.Customizations.Insert(0, new EmailAddressStringsGenerator());