简体   繁体   English

我将如何对数据库逻辑进行单元测试?

[英]How would i unit test database logic?

I am still having a issue getting over a small issue when it comes to TDD. 关于TDD,我仍然遇到一个小问题。

I need a method that will get a certain record set of filtered data from the data layer (linq2SQL). 我需要一种方法,该方法将从数据层(linq2SQL)获得特定记录集的过滤数据。 Please note that i am using the linq generated classes from that are generated from the DBML. 请注意,我使用的是从DBML生成的linq生成的类。 Now the problem is that i want to write a test for this. 现在的问题是我要为此编写测试。

do i: 我是否:

a) first insert the records in the test and then execute the method and test the results a)首先将记录插入测试中,然后执行方法并测试结果

b) use data that might be in the database. b)使用数据库中可能存在的数据。 Not to keen on this logic cause it could cause things to break. 不热衷于这种逻辑会导致事情破裂。

c) what ever you suggest? c)你有什么建议?

You should choose option a). 您应该选择选项a)。

A unit test should be repeatable and has to be fully under your control. 单元测试应该是可重复的,并且必须完全在您的控制之下。 So for the test to be meaningful it is absolutely necessary that the test itself prepares the data for its execution - only this way you can rely on the test outcome. 因此,为了使测试有意义,绝对有必要测试本身准备要执行的数据-只有这样,您才能依赖测试结果。

Use a testdatabase and clean it each time you run the tests. 每次运行测试时,请使用测试数据库并对其进行清理。 Or you might try to create a mock object. 或者,您可以尝试创建模拟对象。

When I run tests using a database, I usually use an in-memory SQLite database. 使用数据库运行测试时,通常使用内存中的SQLite数据库。 Using an in memory db generally makes the tests quicker. 使用内存中的数据库通常可以使测试更快。 Also it is easy to maintain, because the database is "gone" after you close the connection to it. 另外,它很容易维护,因为关闭数据库的连接后数据库便“消失了”。

In the test setup, I set up the db connection and I create the database schema. 在测试设置中,我建立了数据库连接,并创建了数据库模式。 In the test, I insert the data needed by the test. 在测试中,我插入了测试所需的数据。 (your option a)) In the test teardown, I close the connection to the db. (您的选项a))在测试拆卸中,我关闭了与数据库的连接。

I used this approach successfully for my NHibernate applications ( howto 1 | howto 2 + nice summary ), but I'm not that familiar with Linq2SQL. 我已经成功地将这种方法用于NHibernate应用程序( howto 1 | howto 2 +不错的摘要 ),但是我对Linq2SQL并不熟悉。

Some pointers on running SQLite and Linq2SQL are on SO ( link 1 | link 2 ). SO上有一些有关运行SQLite和Linq2SQL的指针( 链接1 | 链接2 )。

Some people argue that a test using a database isn't a unit test. 有人认为使用数据库的测试不是单元测试。 Regardless, I belief that there are situations where you want automated testing using a database: 无论如何,我认为在某些情况下需要使用数据库进行自动测试:

  • You can have an architecture / design, where the database is hard to mock out, for instance when using an ActiveRecord pattern, or when you're using Linq2SQL (although there is an interesting solution in one of the comments to Peter's answer) 您可以拥有一种架构/设计,其中很难模拟出数据库,例如,在使用ActiveRecord模式时,或者在使用Linq2SQL时(尽管在Peter的回答中有一种有趣的解决方案)
  • You want to run integration tests, with the complete system of application and database 您想使用应用程序和数据库的完整系统运行集成测试

What I have done in the past: 我过去所做的事情:

  • Start a transaction 开始交易
  • Delete all data from all the tables in the database 从数据库中的所有表中删除所有数据
  • Setup the reference data all your tests need 设置所有测试所需的参考数据
  • Setup the test data you need in database tables 在数据库表中设置所需的测试数据
  • Run your test 运行测试
  • Abort the transaction 中止交易

This works well provided your database does not have much data in it, otherwise it is slow. 如果您的数据库中没有太多数据,则此方法效果很好,否则速度很慢。 So you will wish to use a test database. 因此,您将希望使用测试数据库。 If you have a test database that is well controlled, you could just run the test in the transaction without the need to delete all data first. 如果您的测试数据库受到良好控制,则可以在事务中运行测试,而无需先删除所有数据。


Try to design your system, so you get mock the data access layer for most of your tests. 尝试设计系统,以便在大多数测试中模拟数据访问层。 It is valid (and often useful) to unit test database code , however the unit tests for your other code should not need to touch the database. 对数据库代码进行单元测试是有效的(并且通常很有用) ,但是其他代码的单元测试不需要接触数据库。

You should consider if you would get more benefits from “end to end” system tests, with unit tests only for your “logic” code. 您应该考虑是否可以从“端到端”系统测试中获得更多好处,而仅针对“逻辑”代码进行单元测试。 This depend to an large extent on other factors within the project. 这在很大程度上取决于项目中的其他因素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM