我在ASP.NET项目中使用Entity Framework,我必须以这种方式设置ApplicationDbContext
构造函数:
public ApplicationDbContext()
: base(DBUtils.Configuration.GetConnection(), false)
{
}
DBUtils.Configuration.GetConnection()
返回DbConnection
的实例,其中包含所有适当的设置(例如连接字符串)。 ApplicationDbContext
正在每个服务构造函数中插入Ninject
。
它完美地工作但在编写测试方法时遇到了一些问题。在其他项目中(使用默认的ApplicationDbContext
构造函数)我只是在db = new Mock<ApplicationDbContext>()
方法中模拟了这样的数据库对象:[TestInitialize]
:
[TestClass]
public class MyServiceTest
{
private MyService _service;
private Mock<ApplicationDbContext> _db;
[TestInitialize]
public void Initialize()
{
_db = new Mock<ApplicationDbContext>();
}
//test methods
}
但现在我需要将DbConnection
(可能是DBUtils.Configuration.GetConnection()
,对吧?)插入:base()
中ApplicationDbContext
的构造函数中,我无法解决任何问题。 。简单地分配如:
[TestInitialize]
public void Initialize()
{
_db = new Mock<ApplicationDbContext>();
_db.Object.Database.Connection = DBUtils.Configuration.GetConnection();
}
或
[TestMethod]
public void Some_Test_Method()
{
//...do stuff...
_db.Setup(x => x.Database.Connection).Returns(DBUtils.Configuration.GetConnection());
//...do stuff...
}
显然不起作用。
如果我没有在测试类中应用连接,我会得到异常:无法为每个带有堆栈跟踪的测试方法找到或加载已注册的.Net Framework数据提供程序:
Result StackTrace:
in System.Data.Common.DbProviderFactories.GetFactory(DataRow providerRow)
in System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName)
in DBUtils.Configuration.GetConnection(String providerName)
in Invoices.Models.ApplicationDbContext..ctor() w C:\Users\user\Documents\Visual Studio 2015\Projects\Invoice\Invoices\Models\IdentityModels.cs:line 61
in Castle.Proxies.ApplicationDbContextProxy..ctor(IInterceptor[] )
--- End of inner exception stack trace ---
第61行恰好是: base(DBUtils.Configuration.GetConnection(), false)
所以问题是:如何在Moq项目中将DbConnection
的实例插入:base()
?
@EDIT:
如果我以这种方式修改ApplicationDbContext
构造函数,那么一切正常:
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
try
{
var connectionString = DBUtils.Configuration.GetConnection().ConnectionString;
this.Database.Connection.ConnectionString = connectionString;
this.SaveChanges();
}
catch (Exception ex)
{
//log exception here
}
}
但就像我之前说过的那样:我宁愿通过将它们插入构造函数来设置数据库连接。