Как вы используете Moles, чтобы молить DbContext от запросов к базе данных в EntityFramework 4.1? - PullRequest
2 голосов
/ 03 сентября 2011

Я использую Entity Framework 4.1 для доступа к базе данных и хотел бы выполнить модульное тестирование следующего кода:

// Get all the entities including children
using (MyContext context = new MyContext())
{
    return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}

Я использую Moles, чтобы исключить зависимость от базы данных, однако я застрял. Какую точку в Entity Framework я должен начать отрицать?

Я следовал этому примеру , но это для LINQ-To-SQL.

Я также думал об отладке / трассировке Entity Framework, чтобы выяснить, какую функцию нужно перехватить перед выполнением вызова базы данных. Однако, похоже, что для Entity Framework 4.1 нет исходного кода для трассировки. См. обсуждение .

Может кто-нибудь подсказать мне, какие функции я должен использовать в DbContext, чтобы я мог получить список EmployeeProfiles обратно?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2013

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

Однако два аргумента, которые я видел для насмешливого EF:

  1. EF ужеабстракция / репозиторий поверх фактической базы данных, поэтому не нужно писать другой репозиторий.
  2. Любой репозиторий, который вы пишете поверх EF, - это ваш код .Поэтому вы должны проверить это, так как рано или поздно вы в конечном итоге добавите логику, которую нужно охватить.

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

Итак, чтобы сделать это с Кротами, вам нужно сделать две вещи.Сначала измените шаблон, который создает ваш DbContext, чтобы типы всех ваших таблиц возвращались IDbSet<> вместо DbSet<>.

Затем, в вашем тестовом проекте, добавьте реализацию тестового класса для IDbSet.Я обнаружил, что этот хорошо работает.

Теперь в своем тесте вы можете сделать следующее:

List<EmployeeProfile> testProfiles = /*your test data here*/;
MMyContext.AllInstances.EmployeeProfilesGet  = (instance) => 
{
    return new InMemoryDbSet<EmployeeProfile>(testProfiles);
};


// Get all the entities including children
using (MyContext context = new MyContext())
{
    return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}

Это быстро, просто и позволяетвы должны проверить свой код вплоть до того момента, когда он оставит ваш контроль.

0 голосов
/ 17 ноября 2011

Мне кажется, что вместо того, чтобы удалять зависимость от EF через шаблон Repository, вы пытаетесь высмеивать специфическое поведение EF. Я не вижу смысла в попытках сделать это, и это будет очень сложно, EF не предназначен для насмешек.

Ваш репозиторий предположительно выглядит примерно так:

public interface IRepository
{
      IEnumerable<EmployeeProfiles> EmployeeProfiles { get; }
}

public class Repository
{
    public IEnumerable<EmployeeProfiles> EmployeeProfiles
    {
        get
        {
            // Get all the entities including children     
            using (MyContext context = new MyContext())     
            {
                return context.EmployeeProfiles.Include("EmployeeProperties").ToList();     
            }
        }
    }
}

Таким образом, вы удалили зависимость хранилища от способа возврата EmployeeProfiles. Теперь вы можете макетировать содержимое вашего сердца (еще не использовали родинки), но с Moq вы бы сделали что-то вроде:

public void TestEmptyList()
{
    var mock = new Mock<IRepository>();
    var expected = new List<EmployeeProfiles>();
    mock.SetupGet(ep => ep.EmployeeProfiles).Returns(expected);

    var actual = mock.Object.EmployeeProfiles;

    Assert.AreEqual(expected, actual);
}

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

Может быть, вы делаете это в любом случае, я не уверен. Я не понимаю, почему вы хотите провести модульное тестирование EF, что бы вы надеялись получить? Это было бы очень сложно, оно не предназначено для насмешек (очень мало интерфейсов / виртуалов). Любое копирование данных, которые вы возвращаете, и это действительно все, что вам действительно интересно, будет сделано, как указано выше.

...