单元测试服务层 - NUnit,NHibernate
问题描述:
我想单元测试一个DEPENDENT服务层,它允许我在不使用NUnit模拟的情况下执行CRUD操作。我知道这可能是不好的做法,但无论如何我都想尝试一下 - 即使测试需要运行一整夜。我的数据是使用NHibernate持久化的,我已经实现了一个“引导”数据库的小型库,我可以在[Setup]方法中使用它。我只是想知道是否有人做了类似的事情,以及引导数据库的最快方法是什么。我使用的是这样的:单元测试服务层 - NUnit,NHibernate
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly("Bla");
new SchemaExport(cfg).Execute(false, true, false);
建立数据库模式。之后,我从一些Excel表中填充一些查找表。
任何反馈将非常感激。谢谢。
基督教
答
Ayende在此blog post中有一个很好的示例。他的例子如下所示,我的评论。
由于配置创建起来很昂贵,因此每次测试运行时只创建一次。使用SQLite内存数据库是因为这是执行查询的最快方式。
public class InMemoryDatabaseTest : IDisposable
{
private static Configuration Configuration;
private static ISessionFactory SessionFactory;
protected ISession session;
public InMemoryDatabaseTest(Assembly assemblyContainingMapping)
{
if (Configuration == null)
{
Configuration = new Configuration()
.SetProperty(Environment.ReleaseConnections,"on_close")
.SetProperty(Environment.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
.SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)
.SetProperty(Environment.ConnectionString, "data source=:memory:")
.SetProperty(Environment.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName)
.AddAssembly(assemblyContainingMapping);
SessionFactory = Configuration.BuildSessionFactory();
}
session = SessionFactory.OpenSession();
new SchemaExport(Configuration).Execute(true, true, false, true, session.Connection, Console.Out);
}
public void Dispose()
{
session.Dispose();
}
}
当使用这个,每个测试开始创建所需的数据。
public class BlogTestFixture : InMemoryDatabaseTest
{
public BlogTestFixture() : base(typeof(Blog).Assembly)
{
}
[Fact]
public void CanSaveAndLoadBlog()
{
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();
}
}
}
答
当写这样集成测试,最重要的事情要记住,你还是应该
- 自动化尽可能地(最好是所有),其中包括设置建立数据库并在使用后再次删除
- 避免General Fixture反模式,这意味着每个测试用例都应该以空数据库开始,而我用Back Door Manipulation填写适当的行。
我在过去几次写了大约my own experiences with testing against databases。
+0
谢谢,我会看看这个。 – cs0815 2010-03-17 10:41:20
外部资源?那些不再是单元测试你正在尝试实现,但集成测试。 – 2010-03-17 09:47:08
好的,我知道。让我们叫它测试然后( - : – cs0815 2010-03-17 10:01:09