Подтвердить что ты не робот

Как лучше всего создать тестовую БД при выполнении TDD?

какая наилучшая практика для создания уровней персистентности тестирования при выполнении сайта ASP.NET(например, сайт ASP.NET MVC)?

Многие примеры, которые я видел, используют Moq (или другую фальшивую фреймворк) в проекте unit test, но я хочу, например... moq из моего уровня персистентности, чтобы мой сайт показывал данные и прочее, но это не пришло из базы данных. Я хочу сделать это последнее. Все издевательские вещи, которые я видел, существуют только в модульных тестах.

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

Что делают другие люди? Примеры и ссылки были бы замечательными:)

UPDATE

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

(также страшно подумать, что я задал этот вопрос почти 11 месяцев назад, с тех пор, как я редактирую это сейчас!)

4b9b3361

Ответ 1

Предполагая, что вы используете шаблон хранилища из Rob Conery MVC Store Front:

http://blog.wekeroad.com/mvc-storefront/mvc-storefront-part-1/

Я последовал за учебником Роба Конери, но столкнулся с тем же, что и вы. Лучше всего переместить созданные вами Mock Repositories в отдельный проект под названием Mocks, после чего вы сможете легко их заменять реальными, когда вы создаете экземпляр своего сервиса. Если вы чувствуете себя авантюристом, вы можете создать factory, который берет значение из файла конфигурации, чтобы создать экземпляр какого-либо макета или реального репозитория,

например.

public static ICatalogRepository GetCatalogRepository(bool useMock)
{
     if(useMock)
          return new FakeCatalogRepository();
     else
          return new SqlCatalogRepository();
}

или использовать инфраструктуру инъекции зависимостей:)

container.Resolve<ICatalogRepository>();

Удачи!

EDIT:. В ответ на ваши комментарии звучит так, будто вы хотите использовать список и LINQ для эмуляции операций db, например. GetProducts, StoreProduct. Я сделал это раньше. Вот пример:

public class Product
{
     public int Identity { get; set; }
     public string Name { get; set; }
     public string Description { get; set; }
     //etc
}

public class FakeCatalogRepository()
{
     private List<Product> _fakes;

     public FakeCatalogCatalogRepository()
     {
          _fakes = new List<Product>();

          //Set up some initial fake data
          for(int i=0; i < 5; i++)
          {
              Product p = new Product
              {
                 Identity = i,
                 Name = "product"+i,
                 Description = "description of product"+i
              };

              _fakes.Add(p);
          }
     }

     public void StoreProduct(Product p)
     {
         //Emulate insert/update functionality

         _fakes.Add(p);
     }

     public Product GetProductByIdentity(int id)
     {
          //emulate "SELECT * FROM products WHERE id = 1234
          var aProduct = (from p in _fakes.AsQueryable()
                         where p.Identity = id
                         select p).SingleOrDefault();

          return aProduct;
     }
}

Означает ли это немного больше смысла?

Ответ 2

Скучно или нет, я думаю, ты на правильном пути. Я предполагаю, что вы создаете fakeRepository, который представляет собой конкретную реализацию вашего IRepository, который, в свою очередь, вводится в ваш уровень обслуживания. Это приятно, потому что в какой-то момент в будущем, когда вы будете довольны формой ваших сущностей и поведением ваших сервисов, контроллеров и представлений, вы можете затем протестировать ваш реальный репозиторий, который будет использовать базу данных для сохранения этих объектов, Конечно, характер этих тестов будет интеграционными тестами, но так же важно, если не более того.

Одна вещь, которая может быть менее скучной для вас, когда придет время создавать ваши реальные репозитории, - это использование nHibernate для вашей настойчивости, вы сможете позволить nhibernate генерировать вашу базу данных после создания карт nhibernate для ваших объектов, предполагая, что вы не нужно использовать устаревшую схему.

Например, у меня есть следующий метод, который вызывается моей SetUpFixture для генерации моей схемы db:

public class SchemaBuilder
{
   public static void ExportSchema()
    {
        Configuration configuration = new Configuration();
        configuration.Configure();
        new SchemaExport(configuration).Create(true, true);
    }
}

и мой SetUpFixture выглядит следующим образом:

[SetUpFixture]
public class SetUpFixture
{
    [SetUp]
    public void SetUp()
    {
        SchemaBuilder.ExportSchema();
        DataLoader.LoadData();
    }
}

где DataLoader отвечает за создание всех моих исходных данных и тестовых данных с использованием реального средства управления.

Это, вероятно, не отвечает на ваши вопросы, но я надеюсь, что это поможет вам успокоить вас в вашем подходе.

Грег

Ответ 3

Я пошел по пути создания таблиц и данных во время метода установки в классе unit test, запуская тесты, а затем выполнял очистку во время разрыва. Да, этот метод работает, но если вы действительно используете свои модульные тесты для целей отладки, вы всегда будете запускать настройку, отлаживать что-то, а затем останавливаться посередине, не делая разрыва. Он очень хрупкий, и вы, вероятно, окажетесь (в конечном счете) с плохими данными в тестовой базе данных и/или непригодными модульными тестами. Я лично считаю, что лучше всего издеваться над слоем базы данных, используя насмешливую структуру. Я понимаю, что иногда лучше всего делать логику в базе данных. Для этих случаев вы можете использовать инструмент, например DBFit для записи тестов для вашего уровня базы данных.

Ответ 4

Хотя я не использую Asp.Net или MVC-структуру, у меня есть необходимость тестировать службы без попадания в базу данных. Ваш вопрос вызвал составление короткого (хорошо, может быть, не столь короткого) резюме того, как я это делаю. Не утверждая, что это лучшее или что-то еще, но оно работает для нас. Мы получаем доступ к данным через репозиторий, и при необходимости мы подключаем репозиторий в памяти, как описано в сообщении.

http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx

Ответ 5

Я использую полную базу данных памяти с SQLite и ActiveRecord. В основном мы удаляем и воссоздаваем базу данных до того, как запускается каждый тест интеграции, чтобы данные всегда находились в известном состоянии. Содержимое базы данных вставляется через код. Итак, пример будет таким:

ActiveRecord.Initalize(lots of parameters)
ActiveRecord.DropSchema();
ActiveRecord.CreateSchema();

а затем мы просто добавим много клиентов или что-то еще, стиль DDD:

customerRepository.Save(customer);

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

Ответ 6

Я знаю, что этот вопрос немного устарел, но я наконец-то придумал ответ:)

Во-первых, используйте RavenDb (Embedded). Он является частью базы данных документов RavenDb. Его полностью в базе данных памяти и отлично работает с модульными тестами:) Я сделал это с MSTest, NUnit и xUnit.

Во-вторых, вы можете использовать NHibernate с SqlLite, если вы не хотите использовать RavenDb. У Айенде есть сообщение об использовании этого.