应该匹配的ActiveRecord匹配器是否违反了"测试行为不实施"规则?

And*_*ndy 4 tdd unit-testing ruby-on-rails shoulda rails-activerecord

例如,如果我should validate_presence_of在我的规范中使用,那只是测试我validate_presence_of在我的模型中有一段代码,那就是测试实现.更重要的是,测试真正的问题并不是那个规范完全没用,"如果我没有填写某个字段,模型是否会成功保存?"

Dav*_*uth 10

一些应该匹配的匹配器不测试实现,它们测试行为.例如,查看(使用)的源allow_valuevalidate_presence_of:#matches?实际上将实例的属性设置为值,并检查是否会导致错误.测试验证的所有shoulda-matchers匹配器(它的 ActiveModel匹配器)我看到的工作方式相同; 他们实际测试模型拒绝坏值.

请注意,如果您信任ActiveModel和ActiveRecord要进行全面测试,则匹配器测试行为或仅测试是否使用宏无关紧要.

单元测试模型的验证绝对有用.假设您正在进行BDD并实现一个创建模型实例的简单表单.您首先要编写验收测试(Cucumber或rspec场景),测试正确填写表单并成功创建实例的快乐路径.然后,您将编写第二个验收测试,其中包含表单中的错误,表明当表单中存在错误时,不会保存任何实例,并且会使用相应的错误消息重新显示表单.

一旦你有一个错误路径场景可以在表单中做出一个错误,你会发现如果你为其他错误编写更多的错误路径场景,它们将是非常重复的 - 唯一的东西不同的是错误的字段值和错误消息.然后你会有很多全栈场景,需要很长时间才能运行.所以不要写第一个错误路径方案.相反,只需为可以捕获每个错误的验证编写单元测试.现在大多数测试都很简单快速.(这是从验收测试下降到单元测试以处理细节的一般BDD技术的具体示例.)

但是,我没有发现shoulda-matchers的ActiveRecord匹配器非常有用.考虑到测试关联的匹配器,我发现我的验收测试总是迫使我将所有关联添加到我需要的模型中,并且在单元测试中没有什么可做的.ActiveRecord匹配测试应用程序看不见的数据库功能(例如have_db_index),如果你是严格测试驱动的,那么我很有用,但我倾向于在那里松懈.此外,对于它的价值,ActiveRecord匹配器不测试行为(这将很难实现),只是使用相应的宏.

我发现一个有用的匹配器ActiveRecord匹配器有用的一个例外是删除依赖对象.我有时会发现没有验收规范已经迫使我处理删除对象时关联对象会发生什么.ActiveRecord的方式来实现这一目标是将添加:dependent选项到belongs_to,has_manyhas_one关联.编写使用早该-匹配器的例子belong_tohave_manyhave_one匹配与.dependent选择是我所知道的测试最便捷的方式.