RSpec'Expect'语法和惯用属性规范

ace*_*reg 12 rspec ruby-on-rails

这应该有一个简单的答案,但我很难找到它(已检查RSpec文档,使用RSpec的EverydayRails测试,谷歌搜索结果).在我的模型规范中,我喜欢包括基本属性规范,如下所示:

describe Foo do
  describe "basic attributes" do
    before { @foo = create(:foo) }
    subject { @foo }

    it { should be_valid }
    it { should respond_to(:color) }
    it { should respond_to(:height) }
    it { should respond_to(:some_other_attribute) }
    it { should respond_to(:you_get_the_idea) }
    ...
Run Code Online (Sandbox Code Playgroud)

我喜欢这些规格,因为如果我的工厂和/或模型中存在某种错误,这些规格可以帮助我快速找到它.

我已将expect语法合并到所有其他规范中,我喜欢它的读取方式,但是如何在这里使用它?一种选择可能是

expect(@foo).to respond_to(:color)
Run Code Online (Sandbox Code Playgroud)

另一个可能是

expect(it).to respond_to(:color)
Run Code Online (Sandbox Code Playgroud)

前者涉及使用should语法避免的重复,但后者对我来说看起来很奇怪(可能只是我).

我意识到这个问题更多的是关于风格而不是功能*,但我们Ruby开发人员对风格很认真,我希望遵循标准实践并拥有可读的,惯用的代码.任何帮助表示赞赏.谢谢.

更新:顺便说一下,我提议的选项都没有实际工作.他们都抛出undefined method 'expect'错误.现在我真的很困惑!

考虑到错误之后,我意识到这是因为should上面的规格在一行块内.那么,混淆是如何用期望语法编写单行块?鉴于此更新,问题非常关乎功能性,我会很高兴听到别人的想法.

4/2015更新

rspec > 3.0添加了另一种处理这些的方法,听起来rspec ~> 4.0会废除should语法.每个迈伦大师赛:

一些用户对如何与期望语法相关以及是否可以继续使用它表示混淆.它将继续在RSpec 3中提供(同样,无论您的语法配置如何),但我们还添加了一个与期望语法更加一致的备用API:

describe Post do
  it { is_expected.to allow_mass_assignment_of(:title) }
end
Run Code Online (Sandbox Code Playgroud)

is_expected非常简单地定义为期望(主题),并且还通过is_expected.not_to匹配器支持负面期望.[...]
在RSpec 3中,我们保留了should语法,默认情况下它是可用的,但如果您在没有明确启用它的情况下使用它,您将收到弃用警告.这将为RSpec 4中默认禁用(或可能被提取到单独的宝石)中铺平道路,同时最大限度地减少通过旧教程来到RSpec的新手的混乱.

Mar*_*off 16

Mylon Marston是RSpec的核心提交者之一,他此解释说你仍然应该使用

it { should be_cool }
Run Code Online (Sandbox Code Playgroud)

如果您禁用了should语法,他提供了一个解决方案,别名expect_itit:

RSpec.configure do |c|
  c.alias_example_to :expect_it
end

RSpec::Core::MemoizedHelpers.module_eval do
  alias to should
  alias to_not should_not
end
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以这样写:

describe User do
  expect_it { to be_valid }
end
Run Code Online (Sandbox Code Playgroud)

  • 需要明确的是:即使你已经配置了禁用`should`语法的东西,一行内容`it {should matcher}`语法仍然可以工作:禁用`should`语法不是猴子修补所有对象应该但是` ExampleGroup#should仍然有效,因为它不需要猴子补丁. (5认同)