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

时间:2017-03-16 10:55:59

标签: c# entity-framework

我正在尝试使用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>()

2 个答案:

答案 0 :(得分:0)

我过去所做的是在我的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;
    }

然后在我的Test课程中,我可以做类似的事情:

[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
    }
 }

答案 1 :(得分:0)

代替使用:

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);
        }