我们在xunit中有一个MVC 3,.Net 4.0应用程序和许多specflow测试,似乎没有问题。为了完全控制我们的测试数据,我们希望在每个场景的开头设置一个干净的数据库,然后再处理它。为此,我们需要在每个场景之前动态更改连接字符串。使用NHibernate会话处理与数据库的连接,我们使用以下代码更改连接字符串:
public class SessionFactoryProvider
{
private static ISessionFactory _sessionFactory;
public static ISessionFactory BuildSessionFactory(bool resetConnection = false)
{
if (ConnectionString == null)
{
ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
}
if (_sessionFactory == null || resetConnection)
{
_sessionFactory = Fluently.Configure()
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<InvoiceMap>().Conventions.AddFromAssemblyOf<CascadeConvention>())
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(ConnectionString))
.ExposeConfiguration(UpdateSchema)
.CurrentSessionContext("web")
.BuildSessionFactory();
}
return _sessionFactory;
}
}
[BeforeScenario]
public static void Setup_Database()
{
var connection = DBHandler.GetAcceptanceDatabaseConnection();
SessionFactoryProvider.ConnectionString = connection.ConnectionString;
var session = SessionFactoryProvider.BuildSessionFactory(true).OpenSession();
}
但看起来Specflow测试和实际应用程序作为两个不同的进程运行,并且它们不共享相同的_sessionFactory,尽管它被定义为静态。因此,更改Setup_Database函数中的连接字符串会更改specflow测试进程的会话,而不是应用程序进程正在使用的连接字符串。
答案 0 :(得分:0)
在测试运行时,必须弄乱连接字符串似乎有点奇怪。
您可以考虑的替代模式是对所有测试使用相同的数据库,但在每次测试后使用TransactionScope进行清理。您可以通过为每个测试打开一个新事务,然后在测试运行后处理该事务来完成此操作。 (您可以将其移动到基类中以避免重复逻辑。)这将确保每个测试都有一个干净的数据库。
我担心我没有在NHibernate中使用它,但您可以查看我对this question的回答,以查看EntityFramework和MSTest的示例。 This short blog post by Ayende Rahien可能有助于理解NHibernate和TransactionScope如何协同工作。