【问题标题】:Do shoulda-matchers' ActiveRecord matchers violate the "test behavior not implementation" rule?shoulda-matchers 的 ActiveRecord 匹配器是否违反“测试行为而不是实现”规则?
【发布时间】:2014-07-27 08:34:09
【问题描述】:

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

【问题讨论】:

  • 我问了a similar question,得到了一些不错的答案,或许对你也有参考。

标签: ruby-on-rails unit-testing tdd rails-activerecord shoulda


【解决方案1】:

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

请注意,如果您相信 ActiveModel 和 ActiveRecord 已经过全面测试,那么匹配器是测试行为还是仅测试使用宏都无关紧要。

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

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

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

我确实发现 shoulda-matchers ActiveRecord 匹配器有用的一个例外是删除依赖对象。我有时发现没有接受规范已经迫使我处理当一个对象时关联对象发生的事情被删除。实现这一点的 ActiveRecord 方法是将:dependent 选项添加到belongs_tohas_manyhas_one 关联。编写一个使用 shoulda-matchers 的 belong_tohave_manyhave_one 匹配器和 .dependent 选项的示例是我知道的最方便的测试方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 2012-02-17
    • 2020-02-17
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    相关资源
    最近更新 更多