Из-за потенциальных различий между Linq-to-Entities (EF4) и Linq-to-Objects мне нужно использовать фактическую базу данных, чтобы убедиться, что мои классы запросов правильно извлекают данные из EF. Sql CE 4 кажется идеальным инструментом для этого, однако я столкнулся с несколькими иконами. Эти тесты используют MsTest.
Проблема в том, что если база данных не воссоздается (из-за изменений модели), данные продолжают добавляться в базу данных после каждого теста, ничего не избавляясь от данных. Это может потенциально вызвать конфликты в тестах, поскольку больше данных возвращается запросами, чем предполагалось.
Моя первая идея состояла в том, чтобы инициализировать TransactionScope
в методе TestInitialize
и отправить транзакцию в TestCleanup
. К сожалению, Sql CE4 не поддерживает транзакции.
Моя следующая идея состояла в том, чтобы удалить базу данных в TestCleanup
с помощью вызова File.Delete()
. К сожалению, похоже, что это не работает после запуска первого теста, так как первый тест TestCleanup
, кажется, удаляет базу данных, но каждый тест после первого не воссоздает базу данных, и, таким образом, она дает ошибку, файл базы данных не найден.
Я попытался изменить теги TestInitialize
и TestCleanup
на ClassInitialize
и ClassCleanup
для моего тестового класса, но это ошибка с NullReferenceException
из-за теста, выполняющегося до ClassInitialize
(или так появляется. ClassInitialize
находится в базовом классе, поэтому, возможно, это вызывает его.)
У меня закончились способы эффективного использования Sql CE4 для тестирования. У кого-нибудь есть лучшие идеи?
Изменить: Я выяснил решение. В моем базовом классе EF unit test я инициирую новый экземпляр контекста данных, а затем вызываю
context.Database.Delete()
и context.Database.Create()
. Тестирование устройства выполняется медленнее, но теперь я могу unit test эффективно использовать реальную базу данных
Заключительное редактирование: После нескольких сообщений электронной почты с Microsoft, выясняется, что
TransactionScope
теперь разрешено в SqlCE с последней версией SqlCE. Однако, если вы используете EF4, есть некоторые ограничения в том, что вы должны явно открыть соединение с базой данных до начала транзакции. В следующем коде показан пример того, как успешно использовать Sql CE для модульного/функционального тестирования:
[TestMethod]
public void My_SqlCeScenario ()
{
using (var context = new MySQLCeModelContext()) //ß derived from DbContext
{
ObjectContext objctx = ((IObjectContextAdapter)context).ObjectContext;
objctx.Connection.Open(); //ß Open your connection explicitly
using (TransactionScope tx = new TransactionScope())
{
var product = new Product() { Name = "Vegemite" };
context.Products.Add(product);
context.SaveChanges();
}
objctx.Connection.Close(); //ß close it when done!
}
}