不能在使用者事務中使用 DROP DATABASE 語句
不確定這個問題是否屬於這裡,但我希望有人可以幫助我。
我已經將集成測試一直深入到數據庫(使用 mssql localDB)。我希望每個測試都使用自己的數據獨立執行 - 我想在每個測試執行之前用我的假數據重新填充數據庫。我試圖通過交易來實現它,但沒有成功。這是我嘗試將其拉下來的方法:
public class TestDbInitializer : DropCreateAlways<MyContext>() { public static List<Item> Items; public override Seed(DbContext context) { Items = new List<Item>(); // Adding items // .. Items.ForEach(x => context.Add(x)); context.SaveChanges(); } } public class BaseTransactionsTests { private TransactionScope _scope [TestInitialize] public void Initialize() { _scope = new TransactionScope(); } [TestCleanup] public void Cleanup() { _scope.Dispose(); } } [TestClass] public class IntegrationTests : BaseTransactionsTests private IDependenciesContainer _container; public static void AssemblyInit(TestContext context) { Database.SetInitializer(new TestDbInitializer()); _container = new DependenciesContainer(); // Registers all my application's dependencies _container.RegisterAll(); } [TestInitialize] public void Initialize() { using (var context = new MyContext("TestsDatabase")) { context.Initialize(true); } } [TestMethod] public void TestAddItem() { var controller = _container.Resolve<MyController>(); var result = controller.AddItem(new Item({Name = "Test"})) var goodResult = result as OkNegotiatedResult<string>(); if (result == null) Assert.Fail("Bad result") using (var context = new MyContext("TestsDatabase")) { Assert.AreEqual(context.Items.Count, TestDbInitializer.Items.Count + 1) } }
我在測試中使用我的依賴注入器,一次註冊所有依賴項(AssemblyInitialize)。
我創建了一個用於測試的數據庫實例,以及一個帶有假數據 Seed 方法的特定 DropCreateAlways 初始化程序,我也將其設置為 AssemblyInitialize 中的初始化程序。
我想在每次測試執行之前用我的假數據重新填充數據庫。對於那種情況,我實現了包含事務範圍的基類。
當我執行測試時,在 TestInitialize 中播種數據庫時會引發以下異常:
DROP DATABASE statement cannot be used inside a user transaction
我應該如何處理?此外,您如何看待我對這些集成測試的實現?有什麼可以改進的?
創建一個單獨的初始化程序,如果數據庫存在則刪除它,然後在任何事務處理程式碼之外創建數據庫。如果由於任何原因失敗,您可以(可能)立即使測試失敗並調查失敗的原因。
來自MSDN:
CREATE DATABASE 語句必須在自動送出模式(預設事務管理模式)下執行,並且不允許在顯式或隱式事務中執行。
如果需要,您可以為每個單獨的測試執行此操作:
DROP DATABASE
如果存在CREATE DATABASE
- 創建必要的 DDL
- 執行 DML 單元測試
DROP DATABASE
但是,那將是矯枉過正。我只是在所有測試開始時創建數據庫,並在最後刪除它。每個單元測試都可以包裝在一個事務中,該事務要麼是回滾的,要麼是送出的,這取決於進一步測試的要求。
我尋找了一個資源來解釋為什麼
CREATE DATABASE
不能在事務中使用,但我找不到。Kenneth Fisher提供了以下 TechNet 連結,其中顯示了在事務中不起作用的所有命令:我們的猜測是,其中很多是不允許的,因為它們會影響文件系統,而文件系統不是事務性的。