
data 工程、 NHibernate.dll 、 FluentNHibernate.dll 和 NUnit.Framework.dll 添加进来。如果你安装了 NUnit NUnit.Framework.dll 可以在 .NET 选项卡里看到。如果你安装了多个版本的 NUnit 的话一定要注意选择的版本。SQL: 在一个方便的旅行装如果你之前没有听说过 SQLite 你会喜欢上它的。这是一个很小的、独立的、并且开源的SQL数据库引擎。更好的是它可以完全的运行在内存当中并且速度非常快。下面是如何设置并且使用它下载 SQLite 提供的 ADO.NET Provider 。下载完整版文件名类似 SQLLit-1.0.65.0-setup.exe。安装完成之后将 System.Data.Sqlite.dll 拷贝到Solution Items 文件夹并且添加到你所有工程的引用当中。下载 SQLite 类库。文件名类似 sqlitedll-3_6_17.zip。提取 SQLite3.dll 到 Solution Items 文件夹。将 System.Data.SQLite.dll 添加到测试工程的引用中。由于 SQLite3.dll 是用 C 编写的是非托管的我们不能直接引用它。为了正确的引用它我们需要其设置成为内容文件。在测试项目上点击右键选择添加现有项添加 SQLite3.dll 。在解决方案资源管理器中找到这个文件点击右键选择属性将它设置为始终复制。这样就会在每次生成项目的时候会自动的将这个文件复制到 bin\Debug 或 bin\Release 目录里。在我以前的随笔里有一个 SQLiteDatabaseScope 类的代码你可以把它添加到你的测试工程里。一个简单的映射测试using System; using System.Linq; using NUnit.Framework; using NHibernate; namespace NStackExample.Data.Tests { [TestFixture] public class CourseMappingTests { [Test] public void CanSaveAndLoadCourse() { using (SQLiteDatabaseScopeCourseMapping Scope new SQLiteDatabaseScopeCourseMapping()) { using (ISession Session Scope.OpenSession()) { Guid ID; Course Course; using (ITransaction Tran Session.BeginTransaction()) { ID (Guid)Session.Save(new Course { Subject SUBJ, CourseNumber 1234, Title Title, Description Description, Hours 3 }); Tran.Commit(); } Session.Clear(); using (ITransaction Tran Session.BeginTransaction()) { Course Session.GetCourse(ID); Assert.AreEqual(SUBJ, Course.Subject); Assert.AreEqual(1234, Course.CourseNumber); Assert.AreEqual(Title, Course.Title); Assert.AreEqual(Description, Course.Description); Assert.AreEqual(3, Course.Hours); Tran.Commit(); } } } } } }下面介绍下它如何工作首先在建立架构的时候获取到一个新的内存中的 SQLite 数据库将 course 保存到数据库中清空 session从数据库中获取到 course测试所有属性以确保它们都是正确的这里你需要知道几件事TestFixture 属性。这是告诉 NUnit 在这个类当中包含测试。Test 属性。这是告诉 NUnit 这个方法是一个测试方法。建议不要使用隐式事务你可能在疑惑为什么我将这些简单的数据库逻辑封装在一个事务中特别是 Session.Get 这只是一个单一的选择语句。在写本系列教程之前我也不会这样做的这是一个新手的错误。在做这项研究的时候我看到了 Ayende 写的 一个测试示例 。他对所有的操作都使用事务甚至是 Session.Get 。我问他为什么这样做的时候他给我发了一个链接NHProfiler Alert 。这一点是非常重要的而且不是显而易见的至少对我来说是这样的。具体的内容大家可以去之前的链接看一下。一个稍微复杂的映射测试在某些时候我们的实体需要有一个父亲例如 section 所以必须在测试孩子之前需要先创建并插入父亲。我们不在此进行级联测试这是一个单独的测试。在这里 section 必须要有两个父亲course 和 term。[Test] public void CanSaveAndLoadSection() { using (SQLiteDatabaseScopeCourseMapping Scope new SQLiteDatabaseScopeCourseMapping()) { using (ISession Session Scope.OpenSession()) { Guid ID; Section Section; Course Course new Course { Subject SUBJ, CourseNumber 1234, Title Title, Description Description, Hours 3}; Term Term new Term { Name Fall 2009, StartDate new DateTime(2009,8,1), EndDate new DateTime(2009,12,1)}; // 我们不在这里进行级联测试所以显式的保存父对象。 using (ITransaction Tran Session.BeginTransaction()) { Session.Save(Course); Session.Save(Term); Tran.Commit(); } Session.Clear(); using (ITransaction Tran Session.BeginTransaction()) { ID (Guid) Session.Save(new Section { Course Course, FacultyName FacultyName, RoomNumber R1, SectionNumber W1, Term Term}); Tran.Commit(); } Session.Clear(); using (ITransaction Tran Session.BeginTransaction()) { Section Session.GetSection(ID); Assert.AreEqual(Course, Section.Course); Assert.AreEqual(FacultyName, Section.FacultyName); Assert.AreEqual(R1,Section.RoomNumber); Assert.AreEqual(W1, Section.SectionNumber); Assert.AreEqual(Term, Section.Term); Tran.Commit(); } } } }