2016-05-04 3 views
0

Я интерфейс, определенный как:Mocking Entity Framework шаблон репозитория

public interface IRepository<TEntity> where TEntity : BaseEntity 
{ 
    ... 

    IEnumerable<TEntity> Get(
     Expression<Func<TEntity, bool>> filter = null, 
     Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
     string includeProperties = ""); 
    ... 
} 

И моя реализация как:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity 
{ 
    internal MyContext context; 
    internal DbSet<TEntity> dbSet; 

    public Repository(MyContext context) 
    { 
     this.context = context; 
     this.dbSet = context.Set<TEntity>(); 
    } 

    public virtual IEnumerable<TEntity> Get(
     Expression<Func<TEntity, bool>> filter = null, 
     Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
     string includeProperties = "") 
    { 
     IQueryable<TEntity> query = dbSet; 

     if (filter != null) 
     { 
      query = query.Where(filter); 
     } 

     foreach (var includeProperty in includeProperties.Split 
      (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) 
     { 
      query = query.Include(includeProperty); 
     } 

     if (orderBy != null) 
     { 
      return orderBy(query).ToList(); 
     } 
     else 
     { 
      return query.ToList(); 
     } 
    } 
} 

И, наконец, мой код, который вызывает это:

Repository.Get(r => 
      r.SourceOrganisationId == id, 
      null, // No ordering 
      "DestinationOrganisation") // Include the company 
      .Select(d => d.DestinationOrganisation).OrderBy(c => c.Name); 

I хочу, чтобы модуль тестировал мой запрос, чтобы убедиться, что у меня есть правильное предложение where, и я включаю в него дополнительный объект.

Я искал, как издеваться над DbContext и DbSet, используя Moq, но не могу видеть, как все еще иметь функциональность EF для включений. Большинство примеров, которые я нашел, издеваются над простым GetById. В принципе, я не хочу издеваться над EF, просто прочитайте его в памяти, а не в Db.

Любые идеи?

Благодаря

+2

Так вы пишете единицы или интеграционные тесты? – Kamo

+1

С точки зрения дизайна, если у Репозитория нет прямой необходимости в 'DbContext', тогда просто передайте' DbSet' в своей инсталляции конструктора, а затем издевайтесь над 'DbSet', который намного проще с moq (IMO) – Nkosi

+0

@Kamo Я пишу модульные тесты, я хочу просто проверить свой запрос, а не фактические данные. @Nkosi Я оставил части реализации Репозитория, но я использую 'DbContext' для проверки/изменения состояния – ADringer

ответ

1

Посмотрев на это еще немного, я понял, что я хочу сделать, это не представляется возможным.

Я хотел был издеваться над БД с памятью в памяти, а затем проверить, работают ли мои запросы, включая метод Include (например, есть некоторые тесты, которые включают связанные объекты, а некоторые нет). Я не хотел насмехаться Include Я действительно хотел, чтобы он действовал как реализованный против моего списка в памяти. Это не возможно из следующего: here:

Одним из примеров такой разности является загрузка связанных данных. Если вы создаете серию блогов, каждая из которых имеет связанные сообщения, то при использовании данных в памяти связанные записи будут всегда загружаться для каждого блога. Однако при работе с базой данных данные будут загружаться только в том случае, если вы используете метод Include.

По этой причине рекомендуется всегда включать в себя некоторый уровень сквозного тестирования (в дополнение к вашим модульным тестам), чтобы ваше приложение корректно работало с базой данных.

0

Существует инструмент под названием Effort, который подходит для тестирования модулей Entity Framework. Может быть стоит посмотреть, соответствует ли это вашим требованиям?

Со своей домашней страницы:

Это в основном провайдер ADO.NET, который выполняет все операции с данными на облегченной основной базе данных памяти в процессе вместо традиционных внешней базы данных

Смежные вопросы