如何使用新的DBContext设置测试组织列表?

时间:2019-03-08 23:54:38

标签: entity-framework unit-testing testing

我有一个应用程序,该应用程序使用多个EF上下文,其中一些首先是代码,某些首先是服务器,并且都是动态的。 我有一堂课,我要在我的应用程序中获取这些上下文。 每个上下文都实现一个接口,例如:

public interface IDatabaseContextSwitcher
{
    IVGSContext GetDatabase(string organization);
    IVGSContext GetDatabase(Guid organizationGuid, string email);
    IVGSServerConn GetServerDatabase(string databaseName);
    IAuthContext GetAuthorizationDatabase();
}
因此,

我有一个在应用程序中实现这些接口实例的类。 (VGSContext,VGSServerConn和AuthContext)。

我正在尝试在测试项目中对它们进行测试。我已经从接口中创建了新类,并计划将一些DbSet插入这些新类中,然后测试我的控制器是否做正确的事情。

但是,我似乎无法弄清楚如何初始化DBSet。

例如以下在添加时消失:

 public AuthContextForTesting()
    {


        Organizations.Add(new Organization()
            {OrganizationName = "Test1", PK_Organization = Guid.Parse("34CE4F83-B3C9-421B-B1F3-42BBCDA9A004")});
        var cnt = Organizations.Count();
    }
    public DbSet<Organization> Organizations { get; set; }

我尝试使用以下方法初始化DBSet: Organizations = new DbSet(); 但是它给出了一个错误,由于权限的原因,这是不允许的。

如何在代码中为测试设置初始数据库集?

1 个答案:

答案 0 :(得分:0)

要执行此操作,首先必须从DBSet派生一个类。可悲的是,我的应用程序同时使用Core EF和EF 6,因此我不得不创建2个类。

EF 6级

public class FakeDbSet<T> : System.Data.Entity.DbSet<T>, IDbSet<T> where T : class
{
    List<T> _data;

    public FakeDbSet()
    {
        _data = new List<T>();
    }

    public override T Find(params object[] keyValues)
    {
        throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
    }

    public override T Add(T item)
    {
        _data.Add(item);
        return item;
    }

    public override T Remove(T item)
    {
        _data.Remove(item);
        return item;
    }

    public override T Attach(T item)
    {
        return null;
    }

    public T Detach(T item)
    {
        _data.Remove(item);
        return item;
    }

    public override T Create()
    {
        return Activator.CreateInstance<T>();
    }

    public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
    {
        return Activator.CreateInstance<TDerivedEntity>();
    }


    public List<T> Local
    {
        get { return _data; }
    }

    public override IEnumerable<T> AddRange(IEnumerable<T> entities)
    {
        _data.AddRange(entities);
        return _data;
    }

    public override IEnumerable<T> RemoveRange(IEnumerable<T> entities)
    {
        for (int i = entities.Count() - 1; i >= 0; i--)
        {
            T entity = entities.ElementAt(i);
            if (_data.Contains(entity))
            {
                Remove(entity);
            }
        }

        return this;
    }

    Type IQueryable.ElementType
    {
        get { return _data.AsQueryable().ElementType; }
    }

    System.Linq.Expressions.Expression IQueryable.Expression
    {
        get { return _data.AsQueryable().Expression; }
    }

    IQueryProvider IQueryable.Provider
    {
        get { return _data.AsQueryable().Provider; }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return _data.GetEnumerator();
    }
}

EF核心必须包含一些接口才能工作。

public class FakeCoreDbSet<T> : Microsoft.EntityFrameworkCore.DbSet<T> , IQueryable, IEnumerable<T> where T : class
{
    List<T> _data;

    public FakeCoreDbSet()
    {
        _data = new List<T>();
    }

    public override T Find(params object[] keyValues)
    {
        throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
    }

    public override EntityEntry<T> Add(T item)
    {
        _data.Add(item);
        //return item;
        return null;
    }

    public override EntityEntry<T> Remove(T item)
    {
        _data.Remove(item);
        //return item;
        return null;
    }

    public override EntityEntry<T> Attach(T item)
    {
        return null;
    }

    public T Detach(T item)
    {
        _data.Remove(item);
        return item;
    }

    public IList GetList()
    {
        return _data.ToList();
    }
    //public override T Create()
    //{
    //    return Activator.CreateInstance<T>();
    //}

    public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
    {
        return Activator.CreateInstance<TDerivedEntity>();
    }
    public List<T> Local
    {
        get { return _data; }
    }


    public override void AddRange(IEnumerable<T> entities)
    {
        _data.AddRange(entities);
        //return _data;
    }

    public override void RemoveRange(IEnumerable<T> entities)
    {
        for (int i = entities.Count() - 1; i >= 0; i--)
        {
            T entity = entities.ElementAt(i);
            if (_data.Contains(entity))
            {
                Remove(entity);
            }
        }

        // this;
    }

    Type IQueryable.ElementType
    {
        get { return _data.AsQueryable().ElementType; }
    }

    System.Linq.Expressions.Expression IQueryable.Expression
    {
        get { return _data.AsQueryable().Expression; }
    }

    IQueryProvider IQueryable.Provider
    {
        get { return _data.AsQueryable().Provider; }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

}

一旦创建了这些对象,我就可以使用MockObjects来获取它们。 注意_dbContextSwitcher是使用Moq创建的类,该Moq调用了不同的数据库。

var vgsdatabase = new Mock<IVGSContext>();
        var settings=new FakeCoreDbSet<Setting>();
        settings.Add(new Setting()
        {
            SettingID = "OrgPrivacy",
            PK_Setting = Guid.NewGuid(),
            UserID = "",
            Value = "No"

        });
        vgsdatabase.Setup(s => s.Setting).Returns(settings);
        _dbcontextSwitcher.Setup(s => s.GetDatabase(It.IsAny<string>())).Returns(vgsdatabase.Object);