2009-12-28 3 views
1

J'ai trouvé ce que je pensais être un great article de Ayende sur la création d'un test de base simple pour les tests unitaires NHib avec SQLite.NHibernate Unités de test unitaires 101

Ma question ici est le code pour un cas d'essai dans un banc d'essai en béton. Dans EX_1 ci-dessous, Ayende encapsule à la fois le save a fetch dans une transaction qu'il commet, et a une Session.Clear entre les deux. Cela fonctionne, bien sûr, mais EX_2 aussi. Toutes choses égales Je préférerais l'EX_2 plus compact et plus lisible. Des réflexions sur pourquoi le code supplémentaire dans EX_1 vaut un peu d'encombrement?

Cheers,
Berryl

==== ===== EX_1

[Fact] 
public void CanSaveAndLoadBlog_EX_1() 
{ 
    object id; 

    using (var tx = session.BeginTransaction()) 
    { 
     id = session.Save(new Blog 
     { 
      AllowsComments = true, 
      CreatedAt = new DateTime(2000,1,1), 
      Subtitle = "Hello", 
      Title = "World", 
     }); 

     tx.Commit(); 
    } 

    session.Clear(); 


    using (var tx = session.BeginTransaction()) 
    { 
     var blog = session.Get<Blog>(id); 

     Assert.Equal(new DateTime(2000, 1, 1), blog.CreatedAt); 
     Assert.Equal("Hello", blog.Subtitle); 
     Assert.Equal("World", blog.Title); 
     Assert.True(blog.AllowsComments); 

     tx.Commit(); 
    } 
} 

==== ===== EX_2

[Fact] 
    public void CanSaveAndLoadBlog_EX_2() 
    { 
     var id = session.Save(new Blog 
           { 
            AllowsComments = true, 
            CreatedAt = new DateTime(2000, 1, 1), 
            Subtitle = "Hello", 
            Title = "World", 
           }); 

     var fromDb = session.Get<Blog>(id); 

     Assert.Equal(new DateTime(2000, 1, 1), fromDb.CreatedAt); 
     Assert.Equal("Hello", fromDb.Subtitle); 
     Assert.Equal("World", fromDb.Title); 
     Assert.True(fromDb.AllowsComments); 

    } 

Répondre

1

Je crois avec NHibernate est encouragé à utiliser les transactions même lorsque vous vous contentez d'interroger. Cochez cet article http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions. De même, votre code EX_2 peut ne pas atteindre la base de données en fonction du type de clé primaire que vous utilisez. Si vous utilisez la clé d'identité que l'auto-incrémentation, NHibernate va frapper la base de données et obtenir une clé primaire, mais si vous utilisez guid, guid.comb, ou hilo, vous ne frapperez pas du tout la base de données. Donc, votre Get serait saisir ce que NHibernate a mis en cache dans la mémoire, sauf si vous faites un changement de validation, puis effacez la session pour que vous sachiez que vous n'avez rien en mémoire.

+0

@Emmanuel - Je ne savais pas qu'il fallait toujours utiliser les transactions pour les opérations de lecture avec Hibernate. Merci de l'avoir signalé. Le chapitre 11.2 des docs semble le confirmer aussi (http://docs.jboss.org/hibernate/core/3.3/reference/fr/html/transactions.html) "Toujours utiliser des limites de transaction claires, même pour la lecture seule opérations. " – dcp

Questions connexes