2012-10-29 9 views
5

Apprezzo molto la potenza di AutoFixture unita alle teorie di XUnit. Recentemente ho adottato l'uso di encapsulating customizations e li ho forniti ai miei test tramite un attributo.Come posso modificare l'apparecchio che il mio attributo dati teoria personalizzato crea per AutoFixture?

In determinate occasioni, ho bisogno di uno scenario unico per eseguire il test con. Quando uso un AutoDomainDataAttribute, come sopra, posso chiedere un IFixture e mi aspetto di ottenere la stessa istanza creata dall'attributo?

Nel mio scenario, sto utilizzando MultipleCustomization per impostazione predefinita per le raccolte, ecc. Tuttavia, in questo caso, voglio solo un singolo elemento inviato al costruttore del SUT. Quindi, ho definito il mio metodo di prova in questo modo:

[Theory, AutoDomainData] 
public void SomeTest(IFixture fixture) { 
    fixture.RepeatCount = 1; 
    var sut = fixture.CreateAnonymous<Product>(); 
    ... 
} 

Sfortunatamente, ricevo un'eccezione durante la creazione del prodotto anonimo. Altri test funzionano bene, se chiedo un parametro Product come metodo con quegli attributi. È solo un problema in questo caso particolare, dove spero che il parametro fixture sia lo stesso creato dal mio AutoDomainDataAttribute.

Il costruttore del prodotto si aspetta un oggetto IEnumerable che normalmente si riempia di 3 elementi, a causa delle personalizzazioni che ho sul posto tramite AutoDomainData. Attualmente, la mia DomainCustomization è una personalizzazione composta composta da MultipleCustomization e AutMoqCustomization, in questo ordine.

L'eccezione è: "InvalidCastException: impossibile eseguire il cast dell'oggetto di tipo" Castle.Proxies.ObjectProxy "per digitare" Prodotto "."

risposta

7

Se è necessario la stessa istanza di fissaggio come quello attivo nel l'attributo, è possibile iniettare la Fixture in se stessa in una personalizzazione, come questo:

public class InjectFixtureIntoItself : ICustomization 
{ 
    public void Customize(IFixture fixture) 
    { 
     fixture.Inject(fixture); 
    } 
} 

Basta ricordarsi di aggiungere questo alla tua CompositeCustomization prima AutoMoqPersonalizzazione, dal momento che IFixture è un'interfaccia e se AutoMoqCustomization viene prima, si otterrà invece un'istanza Mock - AFAICT, questo è ciò che sta accadendo al momento con il proxy Castle dinamico.


Tuttavia, se si realmente bisogno di un esempio di fissaggio, perché non basta scrivere un regolare, metodo di prova imperativo:

[Fact] 
public void SomeTest() 
{ 
    var fixture = new Fixture().Customize(new DomainCustomization()); 
    fixture.RepeatCount = 1; 
    var sut = fixture.CreateAnonymous<Product>(); 
    // ... 
} 

che mi sembra essere molto più facile ... Di tanto in tanto fare questo me stesso ...


Eppure, mi chiedo se non si poteva frase tua API o banco di prova in un modo diverso per rendere l'intera questione andare via. I molto raramente trovo che devo manipolare la proprietà RepeatCount in questi giorni, quindi mi chiedo perché vorresti farlo?

Questo è probabilmente l'argomento di una domanda di Stack Overflow separata, anche se ...

+0

Grazie, Mark. Sono passato immediatamente all'approccio di prova imperativo dopo la pubblicazione qui. Comunque è bello sapere l'alternativa. Infine, il mio test particolare garantisce che l'ultima categoria non possa essere rimossa dal prodotto (ce ne deve essere almeno una). Questa è l'unica volta che ho bisogno di controllare anche il 'RepeatCount'. Grazie ancora! – ventaur

+0

Non potresti aver rimosso 'Categorie.Conta() - Articoli 1' prima come parte della configurazione di prova, quindi testati con una sola a sinistra, non è possibile rimuovere l'ultima? –

+0

Sì, immagino di sì. A volte i programmatori soffrono di complicazioni eccessive. :-) – ventaur

Problemi correlati