2013-03-19 13 views
7

Sto utilizzando una personalizzazione AutoFixture per testare un repository che accede a un DB di SQL Compact.Richiama il metodo Dispose sulla personalizzazione di AutoFixture

Sarebbe molto utile per me cancellare questo database non appena il test è completato. Poiché il db viene creato nel costruttore di personalizzazione, penso che il posto migliore per eliminarlo sia nel metodo di smaltimento.

Il codice che sto pensando è:

internal class ProjectRepositoryCustomization : ICustomization 
{ 
    private readonly String _dbLocation; 

    public ProjectRepositoryCustomization() 
    { 
     var tempDbLocation = Path.Combine(Path.GetTempPath(), "TempDbToDelete"); 
     if (!Directory.Exists(tempDbLocation)) 
     { 
      Directory.CreateDirectory(tempDbLocation); 
     } 

     _dbLocation = Path.Combine(tempDbLocation, Guid.NewGuid().ToString("N") + ".sdf"); 
    } 

    public void Customize(IFixture fixture) 
    { 
     DataContextConfiguration.database = _dbLocation; 

     var dataContextFactory = new BaseDataContextFactory(); 
     var projRepository = new ProjectRepository(dataContextFactory); 
     fixture.Register(() => projRepository); 
    } 

    public void Dispose() 
    { 
     if (File.Exists(_dbLocation)) 
     { 
      File.Delete(_dbLocation); 
     } 
    } 
} 

è possibile fare qualcosa di simile?

+5

'DisposableTrackingCustomization' in AutoFixture può essere utilizzato in vari modi e gestisce roba simile a questa (date un'occhiata al suo impl) Quale framework di test (avere hack per xUnit che salva avendo usato un' using' e/o calling' Fixture.Dispose())? Utilizzando AutoFixture.xUnit.net? Vedi anche https://github.com/AutoFixture/AutoFixture/issues/17 –

risposta

6

Come sottolinea @Ruben Bartelink nei commenti, è possibile . Tuttavia, consiglierei un approccio diverso ed ecco perché.

La gestione della durata degli oggetti è qualcosa che normalmente ci si aspetta di poter fare con un contenitore IoC. AutoFixture, tuttavia, anche se può sembrare un contenitore CIO, è davvero not meant to be one:

AutoFixture condivide molte somiglianze con DI contenitori. È supporta il cablaggio automatico e può essere configurato per creare istanze in molti modi interessanti. Tuttavia, poiché l'attenzione è diversa, è che fa alcune cose meglio e alcune cose non come un contenitore DI.

L'obiettivo principale di AutoFixture è semplificare la creazione di anonymous test data entro determinati limiti configurabili. La sua API è focalizzata sulla permettendo al programmatore di personalizzare modalità di generazione i dati del test, ma non quanto tempo vivrà, dal momento che è assunto solo essere consumato within the context of a test:

AutoFixture è più debole quando si tratta di gestione di vita . Non ci si aspetta che una Fixture esista per più di un caso di test , quindi non ha senso modellare altri stili di vita rispetto a Transient e Singleton. [...] Non ha to, perché non è un DI Container.

I quadri di prova, d'altra parte, sono abbastanza buoni per gestire la durata dei dispositivi di prova. Poiché ciò che stai descrivendo è tipicamente parte della gestione del contesto per un test di integrazione, lo eseguirò prima dello e dopo tutti i test all'interno del dispositivo sono eseguiti.

Ad esempio:

[TestFixture] 
public class WithDatabaseContext 
{ 
    private string dbLocation; 
    private BaseDataContextFactory dataContextFactory 

    protected BaseDataContextFactory DataContextFactory 
    { 
     get { return this.dataContextFactory; } 
    } 

    [TestFixtureSetUp] 
    public void FixtureInit() 
    { 
     // Initialize dbLocation 
     // Initialize dataContextFactory 
    } 

    [TestFixtureTearDown] 
    public void FixtureDispose() 
    { 
     // Delete file at dbLocation 
    } 
} 

Il test potrebbe poi ereditare il contesto e usarlo per configurare AutoFixture:

[TestFixture] 
public void SomeTest : WithDatabaseContext 
{ 
    private IFixture fixture; 

    [SetUp] 
    public void Init() 
    { 
     this.fixture = new Fixture(); 
     this.fixture.Register(
      () => new ProjectRepository(base.DataContextFactory)); 
    } 

    [Test] 
    public void Doing_something_should_return_something_else() 
    { 
     // ... 
    } 
} 

In questo caso, sfruttando il framework di test al fine di gestire il ciclo di vita la banca dati temporanea comunica chiaramente i suoi confini nel contesto dei test.Nascondendolo all'interno di una personalizzazione di AutoFixture, a mio parere, renderemmo molto meno ovvio e, discutibilmente, più difficile da usare.

Problemi correlati