Это хорошая практика для использования Entity Framework в модульных тестах? - PullRequest
2 голосов
/ 18 января 2010

Я пишу NUnit тесты для службы.

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

Единственный недостаток в том, что утомительно писать этот код с использованием SqlCommand, SqlDataReader и т. Д. И возможность использовать EF модель будет намного проще .

Как другие это делают? Рекомендуется ли использовать Entity Framework при написании тестов или для обеспечения точных результатов следует использовать прямые вызовы в базу данных?

Ответы [ 5 ]

1 голос
/ 18 января 2010

Хорошо, давайте скажем так: вам не следует писать модульные тесты, чтобы убедиться, что сама Entity Framework работает. Это работа Microsoft.

Кроме того, некоторые утверждают, что получение базы данных SQL Server в «модульном тесте» вовсе означает, что вы сейчас проводите интеграционное тестирование, а не модульное тестирование. Это независимо от того, как вы это делаете. Я не собираюсь спорить по этому вопросу, однако.

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

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

Но если вас беспокоит кэширование SQL Server (или Entity Framework), ну, с чего бы вы начали? Эти продукты огромны, и вы не сможете провести тестирование всей системы.

Это не означает, что вы должны предполагать, что SQL Server и Entity Framework не имеют дефектов. Но, как правило, вы обнаруживаете ошибки в своей среде с помощью интеграционного тестирования приложения, а не модульного тестирования.

1 голос
/ 18 января 2010

Совсем наоборот. Тесты для нашего уровня DA вообще не касаются базы данных.

Например. У нас есть тест, который вызывает метод Save для сохранения нового объекта данных. Затем он вызывает метод Load, чтобы проверить, что объект может быть загружен обратно. Меня не волнует, был ли объект фактически сохранен в базе данных или нет, все, что меня волнует, - это то, что я могу получить сохраненные объекты. Если EF хочет сделать какое-то умное кеширование и не сохранить сразу, то это нормально для меня.

Учтите, что в будущем мы можем больше не использовать серверную часть SQL-сервера, мы можем перейти на оракул или даже решение NOSQL. Я не хочу, чтобы все мои модульные тесты уровня DA ломались при переключении бэкенда. На самом деле все наоборот, мне нужно, чтобы мои модульные тесты уровня DA продолжали работать без изменений, чтобы я мог проверить, что переключение решения хранения не влияет на семантику или использование уровня DA.

1 голос
/ 18 января 2010

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

То, что я сделал, это свернул мои классы Model в шаблон Repository. Шаблон репозитория был закодирован в интерфейс, чтобы я мог изменить реализацию запросов к базе данных, не затрагивая другие части кода. Это может быть легко издеваться и использоваться для тестирования. Это интерфейс, который я построил.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace App.Core.Repositories
{
    public interface IRepository<TKey, TModel>
        where TKey : IComparable
        where TModel : class
    {
        TModel Only(TKey key);
        IQueryable<TModel> Where(Func<TModel, bool> query);

        TModel Single(Func<TModel, bool> query);
        TModel First(Func<TModel, bool> query);
        IQueryable<TModel> All();

        void Insert(TModel entity);
        void Insert(IEnumerable<TModel> entities);

        void Update(TModel entity);
        void Update(IEnumerable<TModel> entities);

        void Remove(TModel entities);
        void Remove(Func<TModel, bool> query);
        void Remove(IEnumerable<TModel> entities);
    }

    public interface IRepository<TModel> : IRepository<int, TModel> where TModel : class { }

    public interface IRepository : IRepository<int, object> { }
}
0 голосов
/ 19 января 2010

Как уже отмечали Крейг и другие: вы проводите интеграционное тестирование.

Это означает, что я должен ответить на ваш главный вопрос "Нет".

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

Это параноидальная версия, кстати. Второй контекст уже должен помочь.

0 голосов
/ 18 января 2010

Вместо того, чтобы использовать LINQ to Entities, мы используем LINQ to SQL для Манипулирование задней дверью в наших модульных тестах, поскольку оно немного ближе к схеме базы данных.

Однако, вместо того, чтобы уставать от выполнения всего, что связано с SqlCommand и т. Д., Мы устали от синхронизации автоматически сгенерированного кода L2S с реальной базой данных ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...