【问题标题】:Avoiding long foreign key chains with FactoryGirl / rspec使用 FactoryGirl / rspec 避免长外键链
【发布时间】:2015-12-10 07:51:34
【问题描述】:

简短版本:我的数据库中的表之间有很长的外键链,所有表都是必需的/不为空,这意味着我必须在工厂女孩的 7 个不同表中创建记录,在我不这样做的上下文中不需要它们中的大多数。有什么好的办法吗?

长版本:我正在为一家从事商品销售的公司构建应用程序。所以,例如。 Smiths Chips 打电话给他们说:“我们有一种新的‘夏日烧烤’风味,并希望在澳大利亚的这 200 家 Coles 商店中建立过道尽头的特色展示”。这家公司组织临时工在各自的商店执行这项工作。

命名法:
“工作” 是最重要的要求 - 例如“建造过道末端夏季烧烤展示”。一项工作有许多任务。
“任务”是员工在单个商店中执行的工作。
因此,Task 属于 Employee 和 Store。

长外键链为:Task > Store > Suburb > Postcode > Subregion > Region > State

在测试 Job 和 Task 模型时,我需要创建 Task,这意味着在这 6 个其他表中创建记录,我希望避免这样做。

【问题讨论】:

  • 您需要创建任务还是直接存根?
  • 在测试模型时,最好的做法是存根任何其他模型和关联。这将使您的测试更能抵抗变化,但不会降低有效性。
  • 存根可以解决我的一些上下文问题,但不是全部。

标签: ruby-on-rails rspec factory-bot


【解决方案1】:

由于您有外键并且它们在您的数据库中不为空,我的建议是禁用您的测试的外键检查,然后用任何内容填充您的外键。这样,如果您的测试不需要它们,您就不需要创建相关的数据库记录。

这是一个很好的例子,说明如何在 RSpec 中做到这一点

https://gist.github.com/myronmarston/61380bb4500b4d85dd3f

SQLite 的语法是PRAGMA foreign_keys = OFF; / PRAGMA foreign_keys = ON;

【讨论】:

  • 对此的更新:总的来说,我发现它比它的价值更麻烦,我认为最好的方法是不要担心并保留长的外键链。你的测试会慢一点,但你会活下来的。
【解决方案2】:

您可以使用连接表破坏任务 -> 存储外键。 store_tasks 基本上只包含两个外键:一个用于任务,一个用于存储。

所以你最终会得到 Task Store -> ...

这样你就可以独立地测试你需要的任何任务。

唯一的缺点是您可以在数据库中表示“孤立”任务。这不太理想(不利于代表非法状态),但我认为这比 Rob 建议的禁用规范中的所有外键问题要小。

我也总是使用我在生产中使用的同一个数据库进行测试。数据库具有不同的强制规则和语义,并且在生产中失败的情况下可以通过测试。我有时喜欢也能够使用数据库特定的功能:Postgres 对 JSON、窗口函数、全文搜索等有很好的支持,我宁愿接受而不是瞄准最低公分母。拥有不同的数据库进行测试意味着您无法真正做到这一点。

【讨论】:

  • 注意:使用连接表方法并强制任务仅属于一个商店,您将需要 store_tasks 上 task_id 的唯一索引。
  • 我肯定使用与 prod 相同的数据库进行测试。我也可以看到出于测试目的而禁用数据库约束的潜在麻烦——尽管在这一点上(进入项目 3 年),引入连接表也不是微不足道的。现在打算使用 Rob 解决方案,但在明天的旅途中有几个问题要问!
  • 此外,虽然禁用用于测试的数据库约束似乎是个坏主意,但更改应用程序设计也是如此,特别是在测试期间创建更少的数据库记录。我改变的动机只是为了让测试更快一点(即,不创建不需要的数据库记录),而不是让事情本身“更可测试”。因此,仅仅为了提高测试速度而改变设计并不适合我。
  • 我听到了。我从未尝试过(但愿意)的一种方法是将域逻辑转换为命令/事务/操作(无论您想怎么称呼它)模式,并将我的 ActiveRecord 模型视为一个持久层。进行测试以确保持久性像宣传的那样工作,但在内存中使用参数化命令对象执行其他所有操作,并且在大多数测试中根本不接触数据库。您可能不想将其重构为一个 3 年的旧项目,而是一个新项目。
  • ala Trailblazer by @apotnic?
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
相关资源
最近更新 更多