Domanda

Questa domanda unit test ha scatenato un'altra cosa che mi tormenta. Ho di nuovo andata e indietro su tre modi di fare test di unità quando colpisce un database.

  1. Crea oggetti mock e collegare. Questo ha il vantaggio di non aver bisogno di un database, ma di tempo e io non sono sicuro di quanto il ritorno sugli investimenti sto ottenendo. Sono stato sempre in CIO e MOQ un po ', ma sembra ancora doloroso.
  2. Creare un setup e teardown script di database per creare casi noti, e il test per quelli. Ancora una volta, può richiedere molto tempo, ma ancora più facile da creare rispetto finta oggetti maggior parte del tempo. E le altre persone al lavoro può ancora funzionare ammesso che ne abbiano SQL server sul loro localhost.
  3. controllare
  4. manualmente il database dev e modificare test di unità. Intensamente il lavoro manuale, ma se ho un "insieme di test" che non cambia, sembra funzionare bene. Sulla mia macchina, almeno :-).

So che l'opzione 1 è il modo "corretto" per fare test di unità, ma dei tre, questo è probabilmente l'opzione che ho usato il meno (anche se gli ultimi progetti sono stati con IOC, in modo che porta è aperta per me ). Mi rendo conto che un sacco di esso dipende da che cosa esattamente si sta deriso e ciò che è in fase di test, ma quello che mi manca qui?

Se contesto aiuta, io sono in un negozio # C, la scrittura di applicazioni in-house, solo pochi sviluppatori.

È stato utile?

Soluzione

Il primo non dovrebbe essere difficile, se hai un Data Access Layer che espone solo una manciata di metodi IQueryable<T>. C'è un trucco bello si può utilizzare per i dati falsi: basta memorizzare gli oggetti entità in un List<T> e l'uso AsQueryable. Trovo che questo sia più facile che moq per le parti di dati.

Per quanto riguarda CIO, prendo la posizione che è attualmente abusata (essere consapevoli del fatto che il mio parere rappresenta la minoranza di programmatori in questo senso). È possibile utilizzare uno strumento come Moles durante i test per finta, senza dover abusi progettazione del programma. Io non uso del CIO a meno che il progetto in realtà lo richiede.

Altri suggerimenti

avrei sicuramente continuare a utilizzare unit test veri (opzione 1). Mi piace il consiglio di Stefano per questo.

È inoltre possibile trovare le prove di integrazione con un database reale (opzione 2) necessarie da usare come bene (opzione 2). Perché? Poiché parte di ciò che è necessario prova (O / R mapping, la compatibilità con lo schema attuale DB, etc.) non sono coperti da unit test veri e propri.

Come per la configurazione e la logica teardown, che ereditano da questo di solito è sufficiente (utilizzando .NET, NUnit, e SqlServer per il database):

using System.Transactions;
using NUnit.Framework;
namespace Crown.Util.TestUtil
{
    [TestFixture]
    public class PersistenceTestFixture
    {
        public TransactionScope TxScope { get; private set; }

        [SetUp]
        public void SetUp()
        {
            TxScope = new TransactionScope();
        }

        [TearDown]
        public void TearDown()
        {
            if (TxScope != null)
            {
                TxScope.Dispose();
                TxScope = null;
            }
        }
    }
}

Facile come torta.

C'è una suite completa di risposta a questo. La prima cosa da fare è di articolare chiaramente ciò che si sta testando. E 'la facciata di un'API che ha un database dietro di esso, gli oggetti DAO, la struttura del database?

Arrivare a questo aiuterà anche a decidere il modo migliore per le cose di prova. C'è anche da quello che posso vedere in alternativa a quelli che lista. Che è quello di avviare in in-memory database come HSQL ed eseguire le classi e le prove contro quella. Ciò significa che è possibile creare la struttura del database all'inizio di voi prove. Perché è nella memoria che non c'è bisogno di preoccuparsi di avere un server di database, è veloce, e si può caricarlo con dati specifici per il test.

Io uso schernisce un po 'e mentre essi sono grandi per unità di test di una classe, in alcuni casi non lo sono. Essi possono anche perdere portare abbastanza facilmente. Non è raro per qualcosa che funziona con deride, non funzionano quando integrato. Il reasonnfor questo è che si sta caricando il mock con determinate aspettative e le risposte, che si può avere erroneamente interpretate dalla cosa che il mock rappresenta.

Non fraintendetemi, mi piace deride e li usa un bel po '. Ma così facendo non bisogna mai pensare che perché qualcosa è un'unità testato, è corretto. Lo fa aumenta le possibilità, ma sull'integrazione test effettivamente dare certezza al 100%.

Che cosa stai provando davvero che ti fa sentire che questo è difficile?

Se disaccoppiare la logica livello di business e di servizio dal codice persistenza, si dovrebbe easilly essere in grado di isolare il codice che si desidera unit test senza dover un DB.

Uno dei più importanti principi di test di unità è di separare e di prova in isolamento. Quando si ha una chiara comprensione di come farlo, unit testing è facile. Se non lo fai, unit testing diventa dura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top