У меня есть приложение с использованием нескольких контекстов для EF, некоторые из них сначала код, некоторые сначала сервер, и все они динамические. У меня есть класс, который я вызываю, чтобы получить эти контексты в моем приложении. Каждый контекст реализует такой интерфейс, как:

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

Поэтому у меня есть класс, который внедряет экземпляры этих интерфейсов в приложение. (VGSContext, VGSServerConn и AuthContext).

Я пытаюсь проверить это в своем тестовом проекте. Я создал новые классы из интерфейсов, планируя подключить некоторые наборы DbSet к этим новым классам, а затем проверить, что мои контроллеры работают правильно.

Однако я не могу понять, как инициализировать DBSets.

Например, следующее умирает при добавлении:

 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 (); Но выдает ошибку, что это не разрешено из-за разрешений.

Как мне настроить исходные наборы баз данных в коде для моих тестов?

0
done_merson 9 Мар 2019 в 02:54

1 ответ

Лучший ответ

Чтобы сделать это, вы сначала должны наследовать класс от 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 Core должен был включать некоторые интерфейсы для работы.

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, который вызывает различные базы данных.

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);
0
done_merson 11 Мар 2019 в 21:52