none
Как правильно писать Unit тесты для CRUD операций в asp.net mvc? RRS feed

  • Вопрос

  • Привет, друзья! Подскажите пожалуйста, как правильно тестировать операции вставки, чтения, удаления, обновления записей в базе? То есть, стоит ли работать с базой в  unit тесте, или использовать моки, если да, то как?

Ответы

  • Да, моки в этом случае не помогут (операции CRUD с конечным хранилищем). Вот кстати неплохое руководство с MSDN, правда на английском, показывающее вроде именно то, что вы хотите.
    Модератор

Все ответы

  • Кстати, есть книжка, где есть решения интересующих вас проблем. Сандерсон С. ASP.NET MVC 3 Framework. Пролистайте, может найдете что-нибудь полезное
  • Не советую использовать именно данные из БД, так как это сильно усложнит тестирование. Хотя использовать Moq тоже не просто, но намного проще. Да, и как было отмечено высше неплохо про это написано в книге Сандерсона, если с английским проблем нет то рекомендую последнюю версию, про MVC 4. И ещё можете посмотреть видеоматериалы с TechDays. И еще запомните, что Unit тестирование не панацея от всего и покрывать каждый кусок кода тестами не целесообразно.
    Модератор
  • Сандерсона я читал, правда на русском (mvc3). Помню что там пример довольно простой был. 

    А в чем смысл использования moq например для тестирования вставки новой записи в базу? Что толку от такого теста?

    Например в RoR, создается специальная база для тестов... 

    По моему moq больше подходит для тестирования бизнес логики. И например, как с помощью moq протестировать выборку данных из поля DbGeography? где возвращаются структуры типа multipoligon, multipoint..

  • Как я уже отметил высше, Moq - это не панацея. Он предназначен для облегчения (для быстрого создания) тестирования основных и важных частей бизнес логики приложения. "По моему moq больше подходит для тестирования бизнес логики." - да, это примерно так.

    "А в чем смысл использования moq например для тестирования вставки новой записи в базу? Что толку от такого теста?" - опять же, тут делается акцент не на сам конечный результат, а поведение самого кода. Немного трудно это объяснить. Скажем вы написали метод вставки той же записи в базу использующий абстракции и конкретные реализации внедряемые посредством DI контейнера. А потом подсунули другую реализацию (решили изменить код) ошибки которой не видны во время компиляции, так как пока программа не выполнится мы не знаем какого поведения ждать, они показываются только во время выполнения. Вот в этом и помежет вам эта имитация. Т.е. в данном случае нам не нужно просто физически сохранять запись в базу, а именно нужно быстро протестировать само поведение кода (вызывается ли метод, количество, последовательность и т.п.). А в больших проектах такого кода много, то и реализация подобного без Moq тоже станет очень сложной.

    Получается, что Moq не годится да и вовсе в этом случае не к месту, для проверки именно физической вставки записи в базу. Для этого есть ручное тестирование, пока вы напишите подобный тест, тестеры протестируют поведение записи в БД намного быстрей. И не будете же для разных условий писать тонны кода для проверки. Это станет неоправданно сложно и нецелесообразно.

    Модератор
  • Я понимаю о чем вы говорите, но вопрос немного в другом... допустим, у меня есть репозиторий ProductSqlRepository (работает с sql server) и есть ProductMongoDbRepository (работает с базой монго). Оба репозитория реализуют один и тот же интерфейс IProductRepository. И например в зависимости от ситуации мы поставляем в продакшен приложение, в котором в DI контейнере зарегистрирована  одна из реализаций.

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

    Я как думал.. нужно создать тестовую бд, в которую писать, читать, удалять, изменять и т.д. А моки для тестов функционала. Ну как бы разделить тесты на юнит и интеграционные (если я не ошибаюсь). Здесь конечно есть тонкая грань, чтобы не все делать через базу и в тоже время не все через моки.

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

  • Да, моки в этом случае не помогут (операции CRUD с конечным хранилищем). Вот кстати неплохое руководство с MSDN, правда на английском, показывающее вроде именно то, что вы хотите.
    Модератор