简体   繁体   English

使用Effort和dbContext使用Entity Framework创建的数据库进行单元测试

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

相关问题 UnintentionalCodeFirstException | 使用数据库优先使用 Effort.Ef6 进行实体框架单元测试 - UnintentionalCodeFirstException | Entity Framework Unit Testing with Effort.Ef6 using Database First 努力单元测试实体框架6.1.3 DB-first - Effort unit testing Entity framework 6.1.3 DB-first 如何在TDD中创建用于框架测试的Entity Framework DbContext? - How to create an Entity Framework DbContext for unit testing in TDD? 使用实体框架和DbContext测试问题 - Testing problems with Entity framework and DbContext Visual Studio 中的实体框架:数据库不是使用 DbContext 基构造函数创建的 - Entity Framework in Visual Studio: database is not created with DbContext base constructor 单元测试和实体框架 - Unit Testing and Entity Framework Entity Framework 6中的DbContext和数据库初始化器 - DbContext and database initalizer in Entity Framework 6 实体框架代码优先:如何为数据进行单元测试 - Entity Framework Code First: How to seed a database for unit testing 无法在使用Effort框架的单元测试中使用现有数据库 - Unable to use existing database in unit tests with Effort framework 使用IdentityDbContext对Entity Framework 6进行单元测试 - Unit testing Entity Framework 6 with IdentityDbContext
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM