[英]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.