[英]Unit testing with database created by Entity Framework with Effort and dbContext
I am trying to create fake database instance using Effort, but I encountered to a problem. 我试图使用Effort创建假数据库实例,但我遇到了一个问题。
ObjectContextFactory
has a CreateTransistent
generic method which expects an ObjectContext
type to be defined: ObjectContextFactory
有一个CreateTransistent
泛型方法,它需要定义一个ObjectContext
类型:
public static T CreateTransient<T>( ) where T : ObjectContext;
So as far as I understand generic types I can define: 因此,据我所知,泛型类型我可以定义:
class MyObjectContextClass : ObjectContext
{
//Entity definition here
}
So I can do following in unit test class: 所以我可以在单元测试类中做以下事情:
var effortContext = ObjectContextFactory.CreateTransient<MyObjectContextClass>()
So far so good, right? 到目前为止一切都那么好吧? But my context class inherits from
dbContext
class: 但我的上下文类继承自
dbContext
类:
class MyRealDbContextClass : DbContext
{
// Entity definition here
}
I found that DbContext
is a wrapper class and it consist of ObjectContext
我发现
DbContext
是一个包装类,它由ObjectContext
组成
So my question is: how can I retrieve type of my custom ObjectContext
so I can use it in effort static method? 所以我的问题是:我如何检索我的自定义
ObjectContext
类型,以便我可以在努力静态方法中使用它? I need something like: 我需要这样的东西:
var type = MyRealDbContextClass.GetObjectContextType();
So I can: 所以我可以:
var effortContext = ObjectContextFactory.CreateTransient<type>()
What I have done in the past is that I define a method in my Base test class (since this method will be required by all tests) to generate my dbset like: 我过去所做的是在我的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;
}
And then in my Test classes i can do something like: 然后在我的测试类中,我可以做类似的事情:
[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
}
}
Instead of using: 而不是使用:
var effortContext = ObjectContextFactory.CreateTransient<MyObjectContextClass>()
I used: 我用了:
var con = Effort.EntityConnectionFactory.CreatePersistent(connectionString);
Then I can use the effort DB connection in my DbContext class 然后我可以在我的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) { }
}
}
Full example of how I am doing my unit testing: 我如何进行单元测试的完整示例:
My repository method uses a factory to create the context 我的存储库方法使用工厂来创建上下文
Repository: 库:
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);
}
}
}
Factory: 厂:
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);
}
}
My unit test inherits from my factory and returns the effort context instead of the real context 我的单元测试继承自我的工厂并返回工作上下文而不是真实上下文
public class TestContextFactory : IContextFactory
{
public MyDBCoreDBEntities CreateNew()
{
var connectionString = "sampleConnString";
var con = Effort.EntityConnectionFactory.CreatePersistent(connectionString);
return new MyDBCoreDBEntities(con);
}
}
My test initialize method: 我的测试初始化方法:
[TestInitialize]
public void Initialize()
{
ContextFactory = new TestContextFactory();
_Context = ContextFactory.CreateNew();
Repository = new NyDBRepository(ContextFactory);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.