集成测试数据库,我做对了吗?我想在依赖并使用数据库的MVC4应用程序中测试一个方法。我不想使用模拟方法/对象,因为查询可能很复杂,为此创建测试对象会花费太多精力。我发现了集成测试的想法,将测试的数据库操作逻辑包装在一个TransactionScope对象中,该对象在完成时回滚更改。不幸的是,这从一开始就不是一个空数据库,它也使主键计数(即当数据库中已经有一些项目时主键1和2,然后在我运行测试后它取决于4),我不'我不要这个。这是我想出的一个“集成测试”来测试是否实际添加了产品(例如,一旦我拥有正确的基础架构,我想创建更难的测试来检查方法)。[TestMethod]publicvoidProductTest(){//安排使用(newTransactionScope()){myContextdb=newmyContext();ProducttestProduct=newProduct{ProductId=999999,CategoryId=3,ShopId=2,Price=1.00M,Name="测试产品",Visible=true};//行为db.Products.Add(testProduct);db.SaveChanges();//断言Assert.AreEqual(1,db.Products.ToList().Count());//失败,因为数据库中已经有项目}}这引发了很多问题,这里有一个选项:如何从一个空数据库开始?我是否应该使用我自己的上下文和连接字符串将另一个数据库附加到项目?最重要的是,我如何在不破坏旧数据的情况下在真实数据库上正确测试该方法?我整天都在忙于弄清楚如何单元/集成我的数据库逻辑。我希望这里的一些有经验的开发人员可以帮助/编辑影响/更改我的数据库的NDbUnit测试...publicclassIntegrationTests{[TestMethod]publicvoidTest(){stringconnectionString="DataSource=(LocalDb)\v11.0;初始目录=Database_Nieuw;集成安全性=false;”;//上面是唯一有效的连接字符串...并且是“真正的”本地数据库//这没有在Jenkins上使用,但我也许可以附加它???NDbUnit.Core.INDbUnitTestmySqlDatabase=newNDbUnit.Core.SqlClient.SqlDbUnitTest(connectionString);mySqlDatabase.ReadXmlSchema(@"..NDbUnitTestDatabaseNDbUnitTestDatabase.xsd");mySqlDatabase.ReadXml(@"...NDbUnitTestDatabaseDatabaseSeeding.xml");//数据mySqlDatabase.PerformDbOperation(NDbUnit.Core.DbOperationFlag.CleanInsertIdentity);我不想使用模拟方法/对象,因为查询可能很复杂,为此创建测试对象会花费太多精力。这是正确的策略。大多数“有趣”的错误往往发生在客户端代码和(真实)数据库之间的“边界”。如何从空数据库开始?在每次测试之前以编程方式清除数据库。您可以通过将清理代码放在标有[TestInitialize]属性的方法中来自动执行此操作。如果您的数据库恰好使用ONDELETECASCADE,删除所有数据可能就像删除一些“顶级”表一样简单。或者,只要数据库中已有一些数据,就可以编写具有弹性的测试。例如,每个测试都会生成自己的测试数据,并且只对生成的数据使用特定的ID。这提高了性能,因为您不需要运行任何额外的清理代码。最重要的是,我如何在不破坏旧数据的情况下在真实数据库上正确测试该方法?忘掉它。除了可以根据需要丢弃的开发数据库之外,不要对任何其他内容进行此类测试。迟早你会提交一些你不想要的东西,或者持有一些锁的时间超过生产中可接受的时间(例如,通过在调试器中击中断点),或者以不兼容的方式修改模式,或者只是用负载修改它测试。否则会影响真实用户的工作效率……我发现自己处于一种情况,我编写了集成测试,但我没有针对开发数据库执行测试,因为它是一个不断变化的主题。由于我们对持续两周的冲刺使用scrum方法,因此我们采用以下方法:在每个冲刺结束时,我们生成一个与开发数据库的架构相匹配的测试数据库。在大多数情况下,该数据库将在每次测试执行之前在测试数据库服务器上恢复,并在测试完成后丢弃。使用不会更改的可预测数据集填充测试数据库,但需要更改数据的测试除外。配置测试项目以针对测试数据库执行。我们编写的测试分为两部分。仅测试对数据库执行选择查询。对数据库执行插入、更新、删除查询的测试。上述方法使我们始终知道每次测试执行后会发生什么。我们使用MSTest框架编写测试,并利用其在每次测试前后或每组测试前后执行逻辑的能力。下面的代码用于仅执行选择查询的测试。[TestClass]publicclassTests_That_Perform_Only_Select{[ClassInitialize]publicstaticvoidMyClassInitialize(){//这里是恢复测试数据库的代码。}[TestMethod]publicvoidTest1(){//执行检索某些结果集的逻辑。//进行断言。}[TestMethod]publicvoidTest2(){//执行检索某些结果集的逻辑。//进行断言。}[ClassCleanup]publicstaticvoidMyClassCleanup(){//这里是删除数据库的逻辑。这样测试将针对可预测的数据集执行,我们总是知道会发生什么。每个测试类都会执行一次数据库的恢复和删除,这将加快测试执行速度。对于在数据库中执行更改的测试,必须在每次测试执行之前恢复和删除数据库,因为我们不希望下一次测试针对状态未知的数据库执行,因为我们不知道会发生什么。下面是这个场景的代码示例:[TestClass]publicclassTests_That_Perform_Insert_Update_Or_Delete{[TestInitialize]publicvoidMyTestInitialize(){//这里是恢复测试数据库的代码。}[TestMethod]publicvoidTest1(){//执行逻辑。//进行断言。}[TestMethod]publicvoidTest2(){//执行一些逻辑。//进行断言。}[TestCleanup]publicvoidMyClassCleanup(){//这里将逻辑删除数据库。在这个场景中,测试数据库会在每次测试前后被恢复和删除。您应该检查您的函数创建的特定案例。将断言视为您在此测试中专门检查的内容。现在,您的测试正在检查数据库中是否有1条记录。就这样。更有可能的是,您希望您的断言意味着,A)我实际上只是在向数据库中添加一个项目吗?或者,B)我只是将刚刚创建的特定项目添加到数据库中。对于A,你应该做类似的事情...[TestMethod]publicvoidProductTest(){//Arrangeusing(newTransactionScope()){myContextdb=newmyContext();varoriginalCount=db.Products.ToList().Count();ProducttestProduct=newProduct{ProductId=999999,CategoryId=3,ShopId=2,Price=1.00M,Name="TestProduct",Visible=true};//行为db.Products.Add(testProduct);db.SaveChanges();//断言Assert.AreEqual(originalCount+1,db.Products.ToList().Count());//失败,因为数据库中已经有项目}}对于B),我会让你自己解决这个问题,但实际上,你应该检查分配给你的对象的特定ID。以上就是C#学习教程:集成测试数据库,我做对了吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
