【问题标题】:.NET Unit Tests for Reading/Saving data to database用于将数据读取/保存到数据库的 .NET 单元测试
【发布时间】:2009-02-26 13:55:33
【问题描述】:

我读到的关于单元测试的大部分内容都是关于测试你的类及其行为。但是如何测试将数据保存到数据库和从数据库中读取数据。在我们的项目中,保存和读取数据是通过 Flex 应用程序使用的服务完成的(使用 WebORB 作为网关)。例如,一项服务会读取所有有权访问某个模块的用户。您如何测试返回的用户实际上是有权访问该模块的用户?

有时能够测试从数据库中加载数据需要数据库中已有数据。在我们的一些测试中,我们首先需要将大量测试数据保存到数据库中,然后才能测试读取的内容...

同样的事情也适用于存储过程。如果数据库中没有数据,您如何测试 sp。现实情况是,为了测试某些存储过程,我们需要十张表中的数据......

谢谢,利文·卡登

【问题讨论】:

    标签: database unit-testing


    【解决方案1】:

    您可以对 db 操作进行测试,但请尽量避免,否则:

    • 它们的运行速度会比普通测试慢(更有可能是集成测试)
    • 它们需要更多的设置/拆卸工作(db/schema/table 数据)
    • 它们引入了对您的测试框架的外部依赖

    可能也是一种代码味道,您的类没有将数据库相关工作与其他工作分开,例如商业逻辑。然而它可能不是,我们有一个框架测试,它验证自动生成的 SQL 脚本在插入新数据后返回预期的递增标识值,AFAIK 除了针对数据库执行它之外,无法测试该代码是否正常工作。你可以模拟它,或者只是假设如果 SQL 符合你的预期,那么它是可以的,但我不喜欢这个假设,因为很多其他代码都依赖它。

    根据您的测试框架,您应该将这些测试标记为 [Database] 相关的,以便您将它们与其他测试分开。

    【讨论】:

    • 但是你如何测试对于 A 的服务应该返回 Collection A 的数据,而对于 Person B 它应该返回 Collection B?
    • Lieven,这种测试不必依赖于数据库,只要您将执行业务逻辑的代码部分(人 A 返回集合 A,...)从执行数据库请求的代码部分。这可能意味着额外的抽象层(或层)。
    • 对于需要很长时间并且需要更多设置/拆卸的测试,您可以将它们归类为长时间运行(在 xunit 中),然后仅在自动构建上运行这些测试 - 避免每次运行时出现大的紧缩您的其他本地测试。
    • @Si:但是如果存储过程或查询具有业务逻辑来选择人员 A 或人员 B 有权使用的数据怎么办。查询将根据 Person 拥有的权限返回不同的结果。那么你需要假设查询是正确的吗?
    • @SI:如果我决定模拟一些事情,如果您使用像 Subsonic(或实体框架、NHibernate 等)这样的 O/R 映射工具,您实际上是如何做到这一点的。我的业务层使用亚音速层。如何让 Subsonic 层返回 Mock 数据而不是去数据库?
    【解决方案2】:

    这更像是一个集成测试而不是一个单元测试。

    在这种情况下我要做的是构建一个非持久性基础测试,它将测试所需的数据加载到 test-db 中,然后运行单元测试。之后它会处理当前事务,因此不会存储任何数据。

    这里最大的问题是,如果您的客户出现故障 - 您无法运行此类测试...另一个问题是您的 test-db 中的数据将在您每次运行此类测试时重置。

    【讨论】:

      【解决方案3】:

      我同意@Gambrinus。一般来说,几乎不可能对数据层进行单元测试。你能做的最好的就是提供一个强大的数据层接口并在业务层模拟,然后为你的集成测试保存数据质量测试。

      我已经看到有人尝试模拟 ORM 工具(this one for LINQ 让我很开心),但它们不会测试查询的正确性,只是查询是以测试人员认为应该编写的方式编写的。由于测试人员通常是针对 ORM 编写查询的人,因此这没有任何价值。

      【讨论】:

        【解决方案4】:

        尝试使用mbunit。它是一个 .NET 测试框架,允许您在设置中填充数据库,然后回滚您在测试期间对数据库所做的更改,将数据库恢复到之前的状态。有一篇关于它的快速文章here

        【讨论】:

        • 您提供的第二个链接不可用。
        【解决方案5】:

        对保存到数据库和从数据库读取的代码的测试称为Integration Tests。您可以在运行集成测试之前使用数据生成器生成测试数据。集成测试不必像单元测试那样频繁地运行。

        【讨论】:

          【解决方案6】:

          这很有趣,我的项目也有同样的问题。模拟可能是一个很好的方法,但我没有尝试过。通常,我们用数据填充表。我编写单元测试来锻炼给定类的 CRUDL 功能。因此,如果我有一个 Person 类,单元测试包括创建、读取、更新、删除和列出。这些方法倾向于调用存储过程(在大多数情况下),因此它也会测试其中的一部分。

          有一些工具可以转储大量测试数据。

          Sql data generator from Red Gate

          让我们知道哪种方法对您有效。

          【讨论】:

            【解决方案7】:
            • 答:如果您的 FlexApplication 直接访问您的数据库,那么测试起来并不容易。您应该在两者之间有一个可测试的接口/层。
            • B:在“TestSetup-Phase”中将数据放入数据库是正常的。
            • C: 应该可以测试实际触发存储过程的接口。
              • 如果 GUI 不使用存储过程,而仅使用 sql-to-sql,那么测试存储过程的也是“外面”的系统。通常你在实际测试前后都有一个 sp_setup 和 sp_teardown sproc

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-08-11
              • 1970-01-01
              • 2017-12-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-08-21
              相关资源
              最近更新 更多