2015-01-07 42 views
16

ile alt öğede özellik değerinin sabit bir değere ayarlanması Autofixture ile bir üst öğe oluştururken bir alt öğe için bir mülke sabit bir değer atamak mümkün mü? Çocuk örneğindeki tüm özelliklere bir cazibe gibi varsayılan değerler ekler, ancak alt öğe örneğindeki özelliklerden birine belirli bir değeri geçersiz kılmak ve atamak isterim. Bu üst/alt ilişkisi göz önüne alındığında Autofixture

:

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public Address Address { get; set; } 
} 

public class Address 
{ 
    public string Street { get; set; } 
    public int Number { get; set; } 
    public string City { get; set; } 
    public string PostalCode { get; set; } 
} 

ben adres örneğinde İl özelliğine belirli bir değer atamak istiyoruz. Bu test kodunun satırlarında düşünüyordum:

var fixture = new Fixture(); 

var expectedCity = "foo"; 

var person = fixture 
    .Build<Person>() 
    .With(x => x.Address.City, expectedCity) 
    .Create(); 

Assert.AreEqual(expectedCity, person.Address.City); 

Bu mümkün değildir. Ben Autofixture Kişi örneğinin yerine bir adres örneğinde bir şehir özelliğine değer atamak için çalıştığı ... yansıma istisna

System.Reflection.TargetException : Object does not match target type. 

tarafından, sanırım.

Herhangi bir öneriniz var mı?

var fixture = new Fixture(); 

var expectedCity = "foo"; 

// extra step begin 
var address = fixture 
    .Build<Address>() 
    .With(x => x.City, expectedCity) 
    .Create(); 
// extra step end 

var person = fixture 
    .Build<Person>() 
    .With(x => x.Address, address) 
    .Create(); 

Assert.AreEqual(expectedCity, person.Address.City); 

... ama ilk sürümünü veya benzer bir şey (daha kısa ve öz az adımları,) umuyordum:

Ve evet, ben sadece fazladan adım aşağıdaki gibi katkı sağlayabileceğini biliyoruz.

Not: Ben Bir oluşturucudaki yöntemi mı kullanabilirsiniz Autofixture v3.22.0

+0

related: http://stackoverflow.com/a/11657881/11635 –

cevap

5

sorunun hafife almak değil, ama basit çözüm aslında bu olabilir:

özelliklerine açık değerlerin
[Fact] 
public void SimplestThingThatCouldPossiblyWork() 
{ 
    var fixture = new Fixture(); 
    var expectedCity = "foo"; 
    var person = fixture.Create<Person>(); 
    person.Address.City = expectedCity; 
    Assert.Equal(expectedCity, person.Address.City); 
} 

Atama en diller zaten excel şeydir (C# kesinlikle yok), bu yüzden AutoFixture o işlevselliği yarısını çoğaltmak karmaşık bir DSL ihtiyacı olduğunu sanmıyorum. Eğer yeterince sık bu kullanarak sonuna Eğer

fixture.Customize<Address>(c => 
    c.With(addr => addr.City, "foo")); 

var person = fixture.Create<Person>(); 

Bu sarmalanmış değerli olabilir Address

tüm örneklerini oluşturulmasını özelleştirir:

Bütünlüğü için
+0

Çoğumuz, C# 'daki özelliklere açık değerlerin atanmasının (hemen hemen) çaba sarf edilmesinin çoğu için açıktır. Özgün soru, bir ebeveyn/çocuk ilişkisinde, _with_ Otomatik Düzeltme'nin bir özelliğine sabit bir değer atayabilir miydi? Sorunun sebebi sadece estetiğe dayanıyor, çünkü değer atamaları .With (….) Sözdizimini kullanarak çoklu ödevler (“olduğu gibi”) olduğunda “daha ​​güzel” olurdu. Estetik bir yana, cevabınız işi bitirir. –

+0

Özel bir "ISpecimenBuilder" uygulayarak bir değeri düzeltebilir, ancak bir Train Wreck özelliği olduğunda akıcı DSL ile (sanırım) çözemezsiniz. Güzel nişan aldığınız sorudan izlenim aldım, ama eğer kongre temelli bir yaklaşım istiyorsanız, onu paylaşmaktan mutluluk duyarım. –

+0

Hayır, ama yine de teşekkürler. Tren enkazı benim uygulamamın en dış sınırında park edilmiş ve sadece gelen bir veri yapısını modelliyor, bu yüzden ben de bakıyorum ... bir kaç test vakası ile yaşayacağım ... iyi ... daha az güzel ;-) –

-1

kullanıyorum:

var person = this.fixture 
       .Build<Person>() 
       .Do(x => x.Address.City = expectedCity) 
       .Create(); 

Ayrıca enjekte ve fikstür için örnek dondurabilirsiniz:

this.fixture.Inject(expectedCity); 
+0

aslında r denediniz un bu kod? Çalıştırdığımda bir NullReferenceException atar. –

+0

...ve Inject, tüm string özelliklerini beklenenCity değerine ayarlayacaktır - gerçekten ne istediğim değil - –

+0

Gerçekten de, * Do * yöntemi için bir NullReferenceException var, IMO hata olarak kabul edilebilir, çünkü bu yöntem * IPostprocessComposer adından geliyor *, bu nedenle işlem sonrası nesne yapılmalı ve bağımlılıklar oluşturulmalıdır. – sgnsajgon

9

, burada bunu yapmak için başka bir yolu ICustomization iç:

public class AddressConventions : ICustomization 
{ 
    public void Customize(IFixture fixture) 
    { 
     fixture.Customize<Address>(c => 
      c.With(addr => addr.City, "foo")); 
    } 
} 

fixture.Customize(new AddressConventions());