2015-12-09 39 views
1

简短版本:我在数据库中的表之间有一长串外键,所有必需/非空,这意味着我必须在7个不同的表中创建记录工厂女孩,在我不需要他们大多数的情况下。有没有什么好办法解决这个问题?使用FactoryGirl/rspec避免长外键链

长版本:我正在为销售商品的公司开发应用程序。所以,例如。史密斯筹码公司打电话给他们说:“我们有一种新的'夏日烧烤'风味,并希望在澳大利亚各地的这200家Coles商店内建立结束过道特色显示器。”该公司组织休闲工作者在每家商店执行该工作。

命名法:
一个“作业”是涵盖范围广泛的请求 - 例如“建通道夏季BBQ显示的末尾”。工作有很多任务。
a “任务”是员工在单一商店中执行的一项工作。
所以,一个任务属于一个员工和一个商店。

长外键链是:任务>商店>郊区>邮编>次区域>区域>国家

当测试工作和任务模式,我需要创建任务,这意味着在这6个其它创造纪录表,我宁愿避免。

+1

您是否需要创建任务,或者您可以将它们存根? – richessler

+0

当测试模型时,它可能是残留任何其他模型和关联的最佳实践。这将使你的测试更能抵抗变化,但不会有效。 – BroiSatse

+0

存根可以解决我的一些情况下的问题,但不是全部。 –

回答

2

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

下面是如何做到这一点的RSpec的

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

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

+0

更新内容:总体而言,我发现它比它的价值更麻烦,我认为最好的方法是不用担心并保留长期的外键链。你的测试会慢一点,但你会活下去。 –

1

你可以把任务一个很好的例子 - 通过使用>商店外键连接表。 store_tasks基本上只保存两个外键:一个用于任务,另一个用于存储。

所以,你最终会得到任务< - StoreTask - >销售 - > ...

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

唯一的缺点是你可以在数据库中表示一个'孤立'任务。这是不理想的(反对使它不可能代表非法状态),但是我认为比按照Rob的建议禁用所有外键的问题更少。

我总是用我在生产中使用的同一个数据库进行测试。数据库具有不同的强制规则和语义,并且可能会在生产失败的情况下通过测试。我有时候也能够使用数据库特有的功能:Postgres对JSON,窗口函数,全文搜索等有很大的支持,我宁愿拥抱而不是瞄准最低公分母。有一个不同的数据库进行测试意味着你不能这样做。

+0

注意:使用连接表方法并强制任务只属于一个存储,您需要store_tasks上task_id上的唯一索引。 –

+0

我绝对使用相同的数据库进行测试和prod。我也可以看到为了测试目的而禁用数据库约束的潜在问题 - 尽管在这个阶段(进入项目3年),引入连接表也不是微不足道的。现在就开始使用Robs解决方案,但明天在旅途中会问几个问题! –

+0

此外,虽然禁用数据库限制进行测试似乎是一个坏主意,但更改应用程序设计也是一个坏主意,特别是在测试期间创建更少的db记录。我改变的动机是让测试更快一点(即不创建不需要的db记录),而不是让事情本身“更可测试”。所以,仅仅为了提高测试速度而改变设计并不完全适合我。 –