Из-за потенциальных различий между 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!
}
}