[英]UnintentionalCodeFirstException | Entity Framework Unit Testing with Effort.Ef6 using Database First
[英]Unit testing with database created by Entity Framework with Effort and dbContext
我試圖使用Effort創建假數據庫實例,但我遇到了一個問題。 ObjectContextFactory
有一個CreateTransistent
泛型方法,它需要定義一個ObjectContext
類型:
public static T CreateTransient<T>( ) where T : ObjectContext;
因此,據我所知,泛型類型我可以定義:
class MyObjectContextClass : ObjectContext
{
//Entity definition here
}
所以我可以在單元測試類中做以下事情:
var effortContext = ObjectContextFactory.CreateTransient<MyObjectContextClass>()
到目前為止一切都那么好吧? 但我的上下文類繼承自dbContext
類:
class MyRealDbContextClass : DbContext
{
// Entity definition here
}
我發現DbContext
是一個包裝類,它由ObjectContext
組成
所以我的問題是:我如何檢索我的自定義ObjectContext
類型,以便我可以在努力靜態方法中使用它? 我需要這樣的東西:
var type = MyRealDbContextClass.GetObjectContextType();
所以我可以:
var effortContext = ObjectContextFactory.CreateTransient<type>()
我過去所做的是在我的Base測試類中定義一個方法(因為所有測試都需要這個方法)來生成我的dbset,如:
public static IDbSet<T> GenerateSet<T>(IList<T> data) where T : class
{
IQueryable<T> queryable = data.AsQueryable();
IDbSet<T> dbSet = MockRepository.GenerateMock<IDbSet<T>, IQueryable>();
dbSet.Stub(x => x.Provider).Return(queryable.Provider);
dbSet.Stub(x => x.Expression).Return(queryable.Expression);
dbSet.Stub(x => x.ElementType).Return(queryable.ElementType);
dbSet.Stub(x => x.GetEnumerator()).Return(null).WhenCalled(x => queryable.GetEnumerator());
return dbSet;
}
然后在我的測試類中,我可以做類似的事情:
[TestClass()]
public class ConcreteText: TestBase
{
private IMyDbContext _context;
[TestInitialize]
public new void Initialize()
{
base.Initialize();
_context = MockRepository.GenerateMock<IMyDbContext>();
_context.Stub(x => x.DbSetName).PropertyBehavior(); // Name of your dbset
_context.DbSetName = GenerateSet(DbSetCollection); // Define a mock dbset collection
}
}
而不是使用:
var effortContext = ObjectContextFactory.CreateTransient<MyObjectContextClass>()
我用了:
var con = Effort.EntityConnectionFactory.CreatePersistent(connectionString);
然后我可以在我的DbContext類中使用數據庫連接
using System.Data.Common;
using System.Data.Entity;
namespace MC.ClientApi.CompanyProfile.Repository
{
public partial class MyDBCoreDBEntities : DbContext
{
public MyDBCoreDBEntities(string connectionString)
: base(connectionString)
{
}
public MyDBCoreDBEntities(DbConnection connection) : base(connection, true) { }
}
}
我如何進行單元測試的完整示例:
我的存儲庫方法使用工廠來創建上下文
庫:
public class OrganizationOptionsRepository : BaseEFRepository, IOrganizationOptionsRepository
{
private readonly IContextFactory ContextFactory;
public OrganizationOptionsRepository(IContextFactory contextFactory)
{
ContextFactory = contextFactory;
}
public Result<IList<Country>> GetAllCountries()
{
using (var context = ContextFactory.CreateNew())
{
IQueryable<Country> query = context.Countries.OrderBy(x => x.NiceName);
IList<Country> resultList = query.FromCache().ToList();
return Result.Ok(resultList);
}
}
}
廠:
public class ContextFactory : IContextFactory
{
public string ConnectionString { get; set; }
public ContextFactory(string connectionString)
{
ConnectionString = CreateEFConnectionString(connectionString, RepositoryConst.EdmxName);
}
public MyDBCoreDBEntities CreateNew()
{
return new MyDBCoreDBEntities(ConnectionString);
}
}
我的單元測試繼承自我的工廠並返回工作上下文而不是真實上下文
public class TestContextFactory : IContextFactory
{
public MyDBCoreDBEntities CreateNew()
{
var connectionString = "sampleConnString";
var con = Effort.EntityConnectionFactory.CreatePersistent(connectionString);
return new MyDBCoreDBEntities(con);
}
}
我的測試初始化方法:
[TestInitialize]
public void Initialize()
{
ContextFactory = new TestContextFactory();
_Context = ContextFactory.CreateNew();
Repository = new NyDBRepository(ContextFactory);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.