2012-11-01 16 views
1

我是在建设“结识NHibernate的项目)的过程。NHibnernate SQL精简版在内存单元测试不起作用与物理数据库

我的单元测试(NUnit的)提供存储库层与普通mvc站点配置相同,但使用“SQLiteConfiguration.Standard.InMemory()”而不是“MsSqlConfiguration.MsSql2008”。我希望我可以使用流畅的nhibernate和automapping完全相同的方式,但有一个快速的内存分贝测试和应用程序的真实数据库

在存储库构造函数中,它为所有要使用的查询创建Session对象,并实现IDisposable,这将确保会话正确处理。保存物品的方法看起来像:

public void SaveArticle(Article article) 
    {    
     Session.SaveOrUpdate(article);  
     Session.Flush(); 
    } 

到目前为止,MVC站点的所有似乎正常工作,而我的测试都通过。我想我遇到了一个必须成为我设计问题的问题。

到目前为止,我有两个对象:

class Article 
{ 
    public virtual int Id {get; set; } 
    public virtual IList<Tag> Tags {get; set; } 
} 

class Tag 
{ 
    public virtual int Id {get; set; } 
    public virtual string Text {get; set; } 
} 

我只想数据库存储每个标签的一个实例。这么多文章可以使用相同的标签。所以我写了这个测试:

[Test] 
    public void TestDeletingTagWillNotDeleteOthersTagV2() 
    { 
     Article article = new Article(); 
     article.Tags.Add(new Tag { Text = "C#" }); 
     article.Tags.Add(new Tag { Text = "VB" }); 
     Service.SaveArticle(article); 

     Article article2 = new Article(); 
     article2.Tags.Add(new Tag { Text = "C#" }); 
     Service.SaveArticle(article2); 

     Guid article1Id = article.Id; 
     Guid article2Id = article2.Id; 

     article = null; 
     article2 = null; 

     Article article3 = Service.GetArticle(article1Id); 
     Article article4 = Service.GetArticle(article2Id); 

     Assert.AreEqual(2, article3.Tags.Count); 
     Assert.AreEqual(1, article4.Tags.Count); 

     Assert.AreEqual(2, Service.Tags.Count); 

     article3.Tags.RemoveAt(0); 
     Service.SaveArticle(article3); 

     Article article5 = Service.GetArticle(article1Id); 
     Article article6 = Service.GetArticle(article2Id); 

     Assert.AreEqual(1, article5.Tags.Count); 
     Assert.AreEqual(1, article6.Tags.Count); 

     Assert.AreEqual(2, Service.Tags.Count); 
    } 

该测试通过,但我相信它应该失败。 (当你运行MVC站点时,它确实是这样的,即第一篇文章只有一个标记,“VB”而不是“C#”和“VB”。

我相信它因为会话仍然开放nhibernate仍然坚持一切并记得有什么

我的主要问题是我如何测试这与内存分贝?我如何确保在保存和删除共享标签后,文章仍然有他们应该有的?

它创建的表结构是(我觉得是错的,应该有一个链接表):

Article: 
    Id (PK, uniqueid, not null) 
    ........... 

Tag 
    Id (PK, uniqueid, not null) 
    Text (nvarchar, null) 
    Article_id (FK, uniqueid, null) 

不知道如何使用流畅的自动映射设置一个链接表,使一个标签可以在多篇文章共享,一个文章可以有多个标签

相信我发现如何确保标签和文章有链接表:

 configuration.Mappings(m => m.AutoMappings.Add((AutoMap.AssemblyOf<Article>()) 
          .Override<Article>(map => map.IgnoreProperty(x => x.IsPublished)) 
          .Override<Article>(map => map.HasManyToMany(a => a.Tags).Cascade.All()) 
          .Conventions.Add(DefaultCascade.All())) 

回答

0

,如果你只想要独特标签(Text是唯一的),然后使文本唯一和使用会话,以获得唯一实例。对于具有相同文本但不同ID的NHibernate标签是不同的。

// do 
article.Tags.Add(session.Get<Tag>(cSharpId)); 
// or 
article.Tags.Add(session.Query<Tag>().Where(t => t.Text == "C#")); 
// instead of 
article.Tags.Add(new Tag { Text = "C#" }); 

也微观管理会话(刷新)会降低性能。你的测试方法已经做了db调用9 - 13(取决于延迟加载设置)。

而不是服务方法中的Session.Flush();至少引入SaveChanges()其中调用Session.Flush();,以便插入/更新/删除可以正确批处理。