我是一个RSpec新手,但我真的很喜欢编写测试是多么容易,而且当我学习RSpec的新功能时,我会不断重构它们。所以,最初,我有以下内容:
describe Account do
context "when new" do
let(:account) { Account.new }
subject { account }
it "should have account attributes" do
subject.account_attributes.should_not be_nil
end
end
end
然后我了解了its
方法,所以我尝试重写它:
describe Account do
context "when new" do
let(:account) { Account.new }
subject { account }
its(:account_attributes, "should not be nil") do
should_not be_nil
end
end
end
由于its
不接受2个参数而导致失败,但删除消息的工作正常。问题是,如果测试失败,“失败示例”部分下的消息只是说
rspec ./spec/models/account_spec.rb:23 # Account when new account_attributes
并没有太大的帮助。
那么,有没有办法将消息传递给its
,或者更好的是,让它自动输出合理的消息?
答案 0 :(得分:3)
您可以定义RSpec自定义匹配器:
RSpec::Matchers.define :have_account_attributes do
match do |actual|
actual.account_attributes.should_not be_nil
end
failure_message_for_should do
"expected account_attributes to be present, got nil"
end
end
describe Account do
it { should have_account_attributes }
end
答案 1 :(得分:1)
你也可以写:its(:account_attributes) { should_not be_nil }
请参阅https://www.relishapp.com/rspec/rspec-core/v/2-14/docs/subject/attribute-of-subject
请注意,“它”将从rspec-core提取到一个带有rspec 3发布的gem。
答案 2 :(得分:0)
看起来像一个相对简单的猴子补丁将实现你所寻求的。
查看您正在使用的rspec-core gem版本的来源。我在2.10.1。在文件lib/rspec/core/subject.rb
中,我看到定义了its
方法。
这是我的修补版本 - 我更改了def
行和之后的行。
注意 - 这很可能是特定于版本的!从您的版本复制方法并像我一样修改它。请注意,如果rspec-core开发人员对代码进行了重大重组,则补丁可能需要非常不同。
module RSpec
module Core
module Subject
module ExampleGroupMethods
# accept an optional description to append
def its(attribute, desc=nil, &block)
describe(desc ? attribute.inspect + " #{desc}" : attribute) do
example do
self.class.class_eval do
define_method(:subject) do
if defined?(@_subject)
@_subject
else
@_subject = Array === attribute ? super()[*attribute] : _nested_attribute(super(), attribute)
end
end
end
instance_eval(&block)
end
end
end
end
end
end
end
该补丁可能会放在您的spec_helper.rb
。
现在用法:
its("foo", "is not nil") do
should_not be_nil
end
失败时输出:
rspec ./attrib_example_spec.rb:10 # attr example "foo" is not nil
如果省略第二个arg,行为就像未修补的方法一样。