S. *_*ter 4 sql-server testing c# unit-test sql-server-localdb
不确定这个问题是否属于这里,但我希望有人能帮助我。
我已经对数据库进行了集成测试(使用 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)
}
}
Run Code Online (Sandbox Code Playgroud)
我在我的测试中使用我的依赖注入器,一次注册所有依赖(AssemblyInitialize)。
我创建了一个用于测试的数据库实例,以及一个带有假数据 Seed 方法的特定 DropCreateAlways 初始值设定项,我也将其设置为 AssemblyInitialize 中的初始值设定项。
我想在每次测试运行之前用我的假数据重新设置数据库。对于这种情况,我实现了包含事务范围的基类。
当我运行我的测试时,在 TestInitialize 中为数据库播种时会引发以下异常:
DROP DATABASE statement cannot be used inside a user transaction
Run Code Online (Sandbox Code Playgroud)
我该如何处理?此外,您如何看待我对这些集成测试的实现?有什么可以改进的?
创建一个单独的初始化程序,如果数据库存在则删除该数据库,然后在任何事务处理代码之外创建数据库。如果由于任何原因而失败,您可以(可能)立即通过测试并调查失败的原因。
从MSDN:
CREATE DATABASE 语句必须在自动提交模式(默认事务管理模式)下运行,并且不允许在显式或隐式事务中使用。
如果需要,您可以为每个单独的测试执行此操作:
DROP DATABASE 如果存在CREATE DATABASEDROP DATABASE然而,这太过分了。我只是在所有测试开始时创建数据库,并在最后删除它。每个单元测试都可以包含在回滚或提交的事务中,具体取决于进一步测试的要求。
我寻找了一种资源来解释为什么 CREATE DATABASE不能在事务中使用,但我找不到。Kenneth Fisher提供了以下 TechNet 链接,其中显示了在事务中不起作用的所有命令:
我们的猜测是,其中很多是不允许的,因为它们会影响文件系统,这不是事务性的。
| 归档时间: |
|
| 查看次数: |
4080 次 |
| 最近记录: |