Пожалуйста, смотрите мой другой ответ, так как он более новый и намного проще для следующего подхода.
Один вариант, который я могу придумать, будет работать следующим образом ...
(Обратите внимание, что я не проверял это, это просто теория на данном этапе, поэтому не стесняйтесь комментировать, где я мог ошибиться. В конце я сам делал заметки, обращаясь к проблемам, которые я вижу; примечания соответствуют элементам с тегом * или ^)
Предположим, у вас уже есть миграции IM, M1, M2, ..., Mn , где IM - начальная миграция, а миграция Mn - это последняя успешно протестированная миграция. Теперь давайте предположим, что вы хотите протестировать новую миграцию Mn + 1 , которая является результатом (среди прочего) обновления сущности User
, чтобы больше не иметь отдельных свойств FirstName
и LastName
, но вместо этого есть единственное свойство Name
. Давайте дадим ему имя MergeFistAndLastNames
.
Перед тем как приступить к использованию метода тестирования, вам необходимо точно зафиксировать состояние тестируемой системы (SUT) до применения миграции Mn + 1 . Поэтому сделайте следующее:
- Создайте новый тестовый проект для миграции, если он еще не существует.
- Удалите из проекта тестирования миграции весь существующий контент ^ (контент описан в следующих шагах).
- Поместите в проект теста миграции копию всех сущностей в модели, соответствующих Mn , которые необходимо изменить, чтобы сгенерировать Mn + 1 . Отредактируйте их имена, добавив к ним суффикс (например,
Before_MergeFistAndLastNames
). Так как сущность User
должна быть обновлена, поместите ее копию в тестовый проект и назовите ее User_Before_MergeFirstAndLastNames
.
- Сделайте то же самое для любых контекстов *, которые необходимо обновить, чтобы сгенерировать Mn + 1 . Итак, предположим (скажем), что
MembershipContext
необходимо обновить, скопируйте его в тестовом проекте и назовите его MembershipContext_Before_MergeFirstAndLastNames
.
- Наконец, сделайте то же самое для любых сервисов, которые вам нужно будет вызвать для заполнения тестовой базы данных (если вы используете шаблон Repository, это будут ваши реализации репозитория, которые обычно будут вызываться для изменения базы данных и изменение ваших сущностей может вызвать изменение в ваших реализациях репозитория).
Теперь для вашего метода испытаний ^^ вы будете:
- Упорядочить: применить все миграции вплоть до Mn , используя
IMigrator.Migrate
. Затем позвоните в необходимые службы, чтобы заполнить тестовую базу данных **.
- Act: Используя
IMigrator.Migrate
снова, примените миграцию Mn + 1 .
- Утверждение: целостность данных ***.
Примечания:
*: Если контекст копируется в тестовый проект, любые свойства DbSet
в нем, которые соответствуют обновленным объектам, необходимо отредактировать вручную, чтобы использовать скопированные объекты. Например, в приведенном выше примере, если MembershipContext_Before_MergeFirstAndLastNames
имеет свойство DbSet<User> User {get; set;}
, его необходимо изменить на DbSet<User_Before_MergeFirstAndLastNames> User {get; set;}
.
**: Вам может понадобиться позвонить в несколько служб. Если вы используете IoC везде, внедрить скопированные сервисы должно быть относительно просто.
***: Утверждение целостности данных действительно зависит от конкретной миграции, которую вы тестируете, и ее потенциальных последствий. Для приведенного выше примера, возможно, стоит проверить, что пользователь, отобранный с использованием (старого способа) отдельного имени и фамилии, все еще может быть получен через обновленный UserService
, который должен вернуть User
с Name
равна объединению имен и фамилий.
^: Тестовый проект миграции должен быть очищен от всего контента при тестировании новой миграции.
Неформальное доказательство. Предположим, это не нужно. Используя приведенный выше пример, этот проект будет содержать метод тестирования со ссылкой на сущность User
, соответствующую миграции Mn + 1 . Теперь предположим, что сделано обновление до User
, что приводит к более новой миграции Mn + 2 . Существующий метод тестирования может больше не компилироваться, если он ссылается на User
таким образом, что больше не применим. ∎
Вышеупомянутый метод будет хорошо работать в настройке CI, где все предыдущие миграции уже были бы проверены до того, как были включены в производство.При такой настройке имеет смысл интересоваться только тестированием новейшей миграции.^^: Для каждого метода тестирования, который проверяет эффекты миграции Up
, требуется метод обратного теста, который проверяет эффекты соответствующей миграции Down
.