为什么在测试中使用DB会出现问题?
我正在观看 这篇视频文章(由 Jon Galloway 和 Jesse Liberty 撰写)关于构建用于测试的存储库,他们提到拥有数据库不是一个好主意,而应该使用假存储库。他们给出的两个原因是:
1.数据库可能不可用,并且
2.单元测试应该集中在代码级别。
所以关于第一个,我从未遇到过我想要处理任何事情并测试环境的场景。 DB 不可用,他们提出的第二点我不明白。
那么在单元测试中使用数据库是一种不好的做法吗?潜在的危害是什么?
谢谢。
I'm watching this video post (by Jon Galloway and Jesse Liberty) about Building a repository for testing, and they mentioned it's not a good idea to have the DB, and rather one should use a fake repository. The two reasons they gave for that are:
1. The DB may not be available, and
2. Unit tests should be focused at the code level.
So about the first, I never encountered a scenario where I wanted to work on anything and test env. DB wasn't available, and the second point they made I didn't get.
So is it a bad practice using your DB in unit tests? What is the potential harm?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在单元测试中使用数据库而不是在集成测试中使用数据库是不好的。单元测试的想法是独立测试应用程序的不同层。将它们绑定到数据库使它们不再是单元测试,因为它们依赖于数据库,因此它们违背了单元测试最基本的规则之一。
因此,当需要测试实际的数据访问层(访问数据库的层)时,您应该使用集成测试。在这些测试中,您应该设置一个测试数据库。理想情况下,该数据库对于每个集成测试都应该处于已知状态。为了实现这一点,您可以使用脚本在测试夹具设置中创建数据库,并将整个集成测试执行到单个原子事务中,该原子事务将在测试夹具拆卸中回滚,以便数据库再次处于已知状态下一次集成测试。
另一种方法(如果您使用的是 ORM)是在集成测试中设置数据访问层以使用内存数据库(例如 SQLite) 将为每个测试创建并删除它。
It is bad to use database in unit tests but not in integration tests. The idea of unit tests is to test the different layers of your application in isolation. Tying them to a database makes them no longer unit tests as they depend on a database, so they contradict one of the most fundamental rules of a unit test.
So when the time comes to test your actual data access layer (the one that's hitting the database) you should use integration tests. In those tests you should setup a test database. Ideally this database should be in a known state for each integration test. To achieve this you could have scripts that create the database in the test fixture setup and execute the entire integration test into a single atomic transaction that will be rolled back in the test fixture tear down so that the database is again in a known state for the next integration test.
Another approach (if you are using an ORM) is to setup your data access layer in the integration test to use an in-memory database (such as SQLite) which will be created and thorn down for each test.
单元测试应该测试一件事并且没有外部依赖性(即隔离测试)。
一旦涉及文件系统或数据库,或任何外部的东西,它实际上是一个集成测试。
如果单元测试依赖于外部依赖项,则它需要已知的状态,因此很容易崩溃(脆弱)。
正如@Darin 提到的,您可以通过恢复已知的数据库状态、在事务中运行测试并在测试结束时回滚事务来确保已知状态,从而在集成测试中包含数据库。
Unit tests should test one thing and have no external dependencies (i.e. test in isolation).
As soon as the file system or a database, or anything external is involved, it is really an integration test.
If a unit test relies on an external dependency, it requires a known state and therefore becomes prone to breaking (fragile).
As @Darin mentions, you can include a Database in an integration test by ensuring a known state by restoring a known database state, running a test in a transaction and rolling back the transaction at the end of the test.