我想測試一些代碼,為了實現這一點,我需要偽造DAL中定義的DbContext( Entity Framework 6 - Code first
)。它的效果非常好,但是當數據模型類使用TypeName
屬性時,我遇到了一個問題。我做了一個骨架來證明這個問題。
數據模型:
[Table("Customer")]
public class Customer
{
[Key]
public int Id { get; set; }
public string FirstName{ get; set; }
public string LastName { get; set; }
//this line causes the exception
[Column(TypeName = "money")]
public decimal Salary { get; set; }
}
上下文定義
public class MyDbContext : DbContext
{
public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
public MyDbContext(DbConnection connection) : base(connection, true)
{
}
public IDbSet<Customer> Customers { get; set; }
}
以及使用某些數據生成虛假上下文的虛擬方法:
private MyDbContext GenerateFakeDbContext()
{
var connection = DbConnectionFactory.CreateTransient();
var context = new MyDbContext(connection);
var customer = new Customer
{
Id = 1,
FirstName = "X",
LastName = "Y",
Salary = 1000
};
//this line throws the exception
context.Customers.Add(customer);
return context;
}
問題是TypeName
屬性。當它被註釋掉時,測試通過。但是如果啟用它,我會拋出一個System.InvalidOperationException
,然後說
Sequence不包含匹配元素
總結一下,我的問題是:
我建議你看一下EntityTypeConfigurations並在那裡移動你的映射: http : //www.entityframeworktutorial.net/code-first/entitytypeconfiguration-class.aspx
它允許您不考慮當前使用的數據庫並使用它們測試您的實體/接口,而不考慮實體框架。
在我看來,您正在進行集成測試而不是單元測試。要進行單元測試,你應該擺脫真正的DbContext用法(你當前的實現是使用DAL的具體EF實現,但應該使用一些抽象。)
我建議至少將DbContext包裝在一個接口中,這樣你就可以更好地模擬它/ stub它:
public interface IDbContext {
IDbSet<Customer> Customers { get; set; }
}