Из-за потенциальных различий между 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 я инициирую новый экземпляр моего контекста данных, а затем вызываю
context.Database.Delete()
и
context.Database.Create()
. Модульные тесты работают немного медленнее, но теперь я могу эффективно тестировать их, используя реальную базу данных
Окончательное редактирование: После некоторых писем назад и вперед в 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!
}
}