2012-05-02 11 views
5

Sono appena iniziato con RavenDB e mi piace fino ad ora. Sono comunque bloccato su come dovrei unità di testare le azioni del controller che interagiscono con esso.ASP.NET MVC, RavenDb e Unit Testing

Tutte le domande/articoli che ho trovato come questo: Unit testing RavenDb queries dimmi che dovrei usare RavenDB in memoria piuttosto che deriderlo via ma non riesco a trovare un esempio solido di come questo è fatto.

Per esempio io ho un'azione di controllo per aggiungere un dipendente al database (sì, è eccessivamente semplificata, ma non voglio complicare la questione)

public class EmployeesController : Controller 
{ 

    IDocumentStore _documentStore; 
    private IDocumentSession _session; 

    public EmployeesController(IDocumentStore documentStore) 
    { 
    this._documentStore = documentStore; 

    } 

    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
    _session = _documentStore.OpenSession("StaffDirectory"); 
    } 

    protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (_session != null && filterContext.Exception == null) { 
     _session.SaveChanges(); 
     _session.Dispose(); 
    } 
    } 

    [HttpGet] 
    public ViewResult Create() 
    { 
    return View(); 
    } 

    [HttpPost] 
    public RedirectToRouteResult Create(Employee emp) 
    { 
    ValidateModel(emp); 
    _session.Store(emp); 
    return RedirectToAction("Index"); 
    } 

Come si può verificare ciò che è stato aggiunto al il database in un test unitario? Qualcuno ha qualche esempio di test unitari che coinvolgono RavenDb in applicazioni MVC?

Sto usando MSTest se questo è importante, ma sono felice di provare a tradurre test da altri framework.

Grazie.

EDIT

Ok, la mia prova di inizializzazione crea l'archivio di documento che viene iniettato nel costruttore di controllo, ma quando ho eseguito la mia prova l'evento OnActionExecuting non viene eseguito in modo non c'è nessuna sessione da utilizzare e il test fallisce con un'eccezione di riferimento null.

[TestClass] 
public class EmployeesControllerTests 
{ 
    IDocumentStore _store; 

    [TestInitialize] 
    public void InitialiseTest() 
    { 
    _store = new EmbeddableDocumentStore 
    { 
     RunInMemory = true 
    }; 
    _store.Initialize(); 
    } 

    [TestMethod] 
    public void CreateInsertsANewEmployeeIntoTheDocumentStore() 
    { 
    Employee newEmp = new Employee() { FirstName = "Test", Surname = "User" }; 

    var target = new EmployeesController(_store); 
    ControllerUtilities.SetUpControllerContext(target, "testUser", "Test User", null); 

    RedirectToRouteResult actual = target.Create(newEmp); 
    Assert.AreEqual("Index", actual.RouteName); 

    // verify employee was successfully added to the database. 
    } 
} 

Cosa mi manca? Come posso creare la sessione da utilizzare nel test?

+0

Ho aggiornato la mia domanda, vedi sotto –

risposta

7

Dopo aver eseguito il test dell'unità, asserire che è presente un nuovo documento nel database e che ha impostato i campi corretti.

var newDoc = session.Load<T>(docId) 

o

var docs = session.Query<T>.Where(....).ToList(); 

RavenDB in memoria modalità è là in modo che non si dispone di prendere in giro fuori, basta effettuare le seguenti operazioni:

  • Aprire una nuova in -memory embedded doc store (senza dati)
  • Se necessario, inserire i dati necessari per eseguire il test dell'unità
  • RUN th e unit test
  • guardare i dati del negozio in memoria e vedere se è stato aggiornato correttamente

Aggiornamento Se si desidera un campione completo, dare un'occhiata a come il codice RacoonBlog fa , questo è il codice che corre Ayende's blog. Vedere questi 2 file:

+0

Sì, stavo cercando un esempio più completo come ho fatto così lontano :) vedere la mia domanda per ulteriori informazioni. – Nick

3

Come si può verificare ciò che è stato aggiunto alla database in un test unitario?

Non è così. Non testiamo queste cose nei test unitari. Questa è una responsabilità per i test di integrazione, NON per i test unitari.

Se si desidera eseguire il test delle classi di unità, che dipendono da una fonte esterna (come il db), simulare l'accesso al database.

EDIT:

di correggere alcuni errori citati, citerò definizione da MSDN (comunque tutte le altre risorse sono d'accordo con quello):

L'obiettivo primario di unit testing è quello di prendere il pezzo più piccolo del software verificabile nell'applicazione, isolarlo dal resto del codice e determinare se si comporta esattamente come previsto.

Senza prendere in giro, si ignorano i principi di base del test dell'unità: isolamento e test del pezzo più piccolo possibile.Il test unitario deve essere persistente-ignorante e non dovrebbe basarsi su qualche classe esterna. Cosa succede se il db cambia nel tempo? Riscrivi tutti i test, anche se la funzionalità rimane esattamente la stessa?

COME ON. Puoi darmi -1 quante volte vuoi, ma questo non ti farà star bene.

+2

Questo è vero, ma il modo in memoria di RavenDB rende così facile da fare test di integrazione , che spesso non devi preoccuparti di fare test di unità e deridere tutto –

+1

@MattWarren, hmm, e pensavo che stessimo scrivendo test per essere persistenti-ignoranti ... Non è una domanda se sia facile o no . Il test unitario non dovrebbe MAI andare al di fuori dei confini della classe, altrimenti sarebbe un test di integrazione. Non importa se hai il tuo db in memoria, in file o su un server completamente diverso. Il principio rimane lo stesso che temo ... – walther

+0

Di solito con un RDBMS come SQL Server, avrei un repository e lo prendevo in giro per questi test. Tuttavia, tutti gli articoli che ho letto su RavenDB, incluso il blog di Ayende, dicono di non farlo ... quindi ho pensato di provarlo. – Nick