使用 PostgreSQLConfiguration 的单元测试 FluentNhibernate
UnitTest FluentNhibernate using PostgreSQLConfiguration
在设置我们的新架构时,我遵循了使用 NHibernate
和 MsSql2008
配置的指南。
我们没有使用 MsSql2008
,而是使用 Postgresql
。这一切的配置都很好,它保存到数据库等。
我正在尝试编写单元测试来测试 UoW
,但我无法使 InMemory
配置正常工作。
我遵循的指南使用了以下提供程序:
public class InMemoryNHibernateConfigurationProvider : NHibernateConfigurationProvider
{
public override Configuration GetDatabaseConfiguration()
{
var databaseDriver = SQLiteConfiguration.Standard.InMemory().ShowSql();
return CreateCoreDatabaseConfiguration(databaseDriver);
}
public static void InitialiseDatabase(Configuration configuration, ISession session)
{
new SchemaExport(configuration).Execute(true, true, false, session.Connection, Console.Out);
}
}
我的标准(非单元测试)配置如下所示:
public abstract class NHibernateConfigurationProvider : INHibernateConfigurationProvider
{
public abstract Configuration GetDatabaseConfiguration();
public Configuration CreateCoreDatabaseConfiguration(
IPersistenceConfigurer databaseDriver,
Action<Configuration> databaseBuilder = null)
{
var fluentConfiguration =
Fluently.Configure()
.Database(databaseDriver)
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Organisation>(new DefaultMappingConfiguration())
//.Conventions.AddFromAssemblyOf<IdGenerationConvention>()
.UseOverridesFromAssemblyOf<OrganisationMappingOverride>()));
if (databaseBuilder != null)
{
fluentConfiguration.ExposeConfiguration(databaseBuilder);
}
return fluentConfiguration.BuildConfiguration();
}
}
public class PostgreSQLServerNHibernateConfigurationProvider : NHibernateConfigurationProvider
{
private static readonly string NpgsqlConnectionString = ConfigurationManager.ConnectionStrings["ProdDBConnection"].ConnectionString;
public override Configuration GetDatabaseConfiguration()
{
return CreateCoreDatabaseConfiguration(
PostgreSQLConfiguration.Standard.ConnectionString(NpgsqlConnectionString).
Dialect("NHibernate.Dialect.PostgreSQL82Dialect").ShowSql(),
BuildDatabase);
}
....... // Other Methods etc
}
如何编写一个 InMemoryConfigurationProvider
来测试使用 PostgresqlConfiguration
而不是 SqlLiteCOnfiguration
。 PostgresqlConfiguration
没有 InMemory
选项。
我是否实施创建另一个数据库并在拆卸时将其删除的配置?或者还有其他方法吗?
使用 sqlite 效果非常好,虽然它确实与我们使用的 SQL-server 有一些差异,但它们非常小,对于测试目的来说无关紧要。
话虽如此,这就是我们设置测试的方式:
我们想要从数据库 write/read 扩展 SqLiteTestBase
class 的所有测试用例。这样他们都可以访问由 basesetup 方法创建的会话,并且可以根据需要设置 daos / 存储库。
使用这种方法,我们也总是为每个测试用例获得一个全新的数据库。
更新:
在进一步尝试之后,我实际上发现您必须对其进行一些修改才能使用 InMemory
(我们之前使用的是磁盘上文件支持的 sqlite)。所以更新的(完整的)设置看起来像这样:
private Configuration _savedConfig;
[SetUp]
public void BaseSetup()
{
FluentConfiguration configuration =
Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.InMemory)
.ExposeConfiguration(
x => x.SetInterceptor(new MultiTenancyInterceptor(ff)))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<IRepository>())
.Mappings(m => m.FluentMappings.ExportTo("c:\temp\mapping"))
.ExposeConfiguration(x => _savedConfig = x) //save the nhibernate configuration for use when creating the schema, in order to be able to use the same connection
.ExposeConfiguration(x => ConfigureEnvers(x))
.ExposeConfiguration(x => ConfigureListeners(x));
ISessionFactory sessionFactory;
try
{
sessionFactory = configuration.BuildSessionFactory();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
throw;
}
_session = sessionFactory.OpenSession();
BuildSchema(_savedConfig, _session);
}
private void BuildSchema(Configuration config, ISession session)
{
new SchemaExport(config)
.Execute(false, true, false, session.Connection, null);
}
你必须跳过所有这些环节才能使用内存中版本的 Sqlite 的原因是数据库被绑定到连接上。您必须使用创建数据库的相同连接来填充模式,因此我们必须保存 Configuration
对象,以便我们稍后可以在创建连接时导出模式。
有关更多详细信息,请参阅此博文:http://www.tigraine.at/2009/05/29/fluent-nhibernate-gotchas-when-testing-with-an-in-memory-database/
N.B:这只显示了数据库的设置。我们有一些代码也用标准值(用户、客户、主数据等)填充数据库,但为简洁起见我省略了它。
在设置我们的新架构时,我遵循了使用 NHibernate
和 MsSql2008
配置的指南。
我们没有使用 MsSql2008
,而是使用 Postgresql
。这一切的配置都很好,它保存到数据库等。
我正在尝试编写单元测试来测试 UoW
,但我无法使 InMemory
配置正常工作。
我遵循的指南使用了以下提供程序:
public class InMemoryNHibernateConfigurationProvider : NHibernateConfigurationProvider
{
public override Configuration GetDatabaseConfiguration()
{
var databaseDriver = SQLiteConfiguration.Standard.InMemory().ShowSql();
return CreateCoreDatabaseConfiguration(databaseDriver);
}
public static void InitialiseDatabase(Configuration configuration, ISession session)
{
new SchemaExport(configuration).Execute(true, true, false, session.Connection, Console.Out);
}
}
我的标准(非单元测试)配置如下所示:
public abstract class NHibernateConfigurationProvider : INHibernateConfigurationProvider
{
public abstract Configuration GetDatabaseConfiguration();
public Configuration CreateCoreDatabaseConfiguration(
IPersistenceConfigurer databaseDriver,
Action<Configuration> databaseBuilder = null)
{
var fluentConfiguration =
Fluently.Configure()
.Database(databaseDriver)
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Organisation>(new DefaultMappingConfiguration())
//.Conventions.AddFromAssemblyOf<IdGenerationConvention>()
.UseOverridesFromAssemblyOf<OrganisationMappingOverride>()));
if (databaseBuilder != null)
{
fluentConfiguration.ExposeConfiguration(databaseBuilder);
}
return fluentConfiguration.BuildConfiguration();
}
}
public class PostgreSQLServerNHibernateConfigurationProvider : NHibernateConfigurationProvider
{
private static readonly string NpgsqlConnectionString = ConfigurationManager.ConnectionStrings["ProdDBConnection"].ConnectionString;
public override Configuration GetDatabaseConfiguration()
{
return CreateCoreDatabaseConfiguration(
PostgreSQLConfiguration.Standard.ConnectionString(NpgsqlConnectionString).
Dialect("NHibernate.Dialect.PostgreSQL82Dialect").ShowSql(),
BuildDatabase);
}
....... // Other Methods etc
}
如何编写一个 InMemoryConfigurationProvider
来测试使用 PostgresqlConfiguration
而不是 SqlLiteCOnfiguration
。 PostgresqlConfiguration
没有 InMemory
选项。
我是否实施创建另一个数据库并在拆卸时将其删除的配置?或者还有其他方法吗?
使用 sqlite 效果非常好,虽然它确实与我们使用的 SQL-server 有一些差异,但它们非常小,对于测试目的来说无关紧要。
话虽如此,这就是我们设置测试的方式:
我们想要从数据库 write/read 扩展 SqLiteTestBase
class 的所有测试用例。这样他们都可以访问由 basesetup 方法创建的会话,并且可以根据需要设置 daos / 存储库。
使用这种方法,我们也总是为每个测试用例获得一个全新的数据库。
更新:
在进一步尝试之后,我实际上发现您必须对其进行一些修改才能使用 InMemory
(我们之前使用的是磁盘上文件支持的 sqlite)。所以更新的(完整的)设置看起来像这样:
private Configuration _savedConfig;
[SetUp]
public void BaseSetup()
{
FluentConfiguration configuration =
Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.InMemory)
.ExposeConfiguration(
x => x.SetInterceptor(new MultiTenancyInterceptor(ff)))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<IRepository>())
.Mappings(m => m.FluentMappings.ExportTo("c:\temp\mapping"))
.ExposeConfiguration(x => _savedConfig = x) //save the nhibernate configuration for use when creating the schema, in order to be able to use the same connection
.ExposeConfiguration(x => ConfigureEnvers(x))
.ExposeConfiguration(x => ConfigureListeners(x));
ISessionFactory sessionFactory;
try
{
sessionFactory = configuration.BuildSessionFactory();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
throw;
}
_session = sessionFactory.OpenSession();
BuildSchema(_savedConfig, _session);
}
private void BuildSchema(Configuration config, ISession session)
{
new SchemaExport(config)
.Execute(false, true, false, session.Connection, null);
}
你必须跳过所有这些环节才能使用内存中版本的 Sqlite 的原因是数据库被绑定到连接上。您必须使用创建数据库的相同连接来填充模式,因此我们必须保存 Configuration
对象,以便我们稍后可以在创建连接时导出模式。
有关更多详细信息,请参阅此博文:http://www.tigraine.at/2009/05/29/fluent-nhibernate-gotchas-when-testing-with-an-in-memory-database/
N.B:这只显示了数据库的设置。我们有一些代码也用标准值(用户、客户、主数据等)填充数据库,但为简洁起见我省略了它。