我该怎么做:
it { should have_constant(:FIXED_LIST) }
在我的模型(活动记录)中,我有FIXED_LIST = 'A String'
它不是数据库属性或方法,我无法使用responds_to
或has_attribute
测试它(它们失败了)。我可以用什么来检查它。- 顺便说一句,我安装了应该匹配器。
根据 David Chelimsky 的回答,我可以通过稍微修改他的代码来实现这一点。
在文件 spec/support/utilities.rb(或 spec/support 中的其他文件)中,您可以输入:
RSpec::Matchers.define :have_constant do |const|
match do |owner|
owner.const_defined?(const)
end
end
注意使用“RSpec::Matchers.define”而不是“matchers”
这允许测试规范中的常量,例如:
it "should have a fixed list constant" do
YourModel.should have_constant(:FIXED_LIST)
end
注意使用“have_constant”而不是“have_const”
它读起来有点傻,但是:
describe MyClass do
it { should be_const_defined(:VERSION) }
end
原因是 Rspec 对以be_
and开头的方法有“神奇的”匹配器have_
。例如,it { should have_green_pants }
将断言返回的has_green_pants?
方法。subject
true
以同样的方式,一个例子it { should be_happy }
会断言返回的happy?
方法。subject
true
因此,该示例it { should be_const_defined(:VERSION) }
断言const_defined?(:VERSION)
返回true
.
如果你想说have_constant
你可以为它定义一个自定义匹配器:
matcher :have_constant do |const|
match do |owner|
owner.const_defined?(const)
end
end
MyClass.should have_const(:CONST)
如果您尝试使用单行语法,则需要确保主题是类(而不是实例)或在匹配器中检查它:
matcher :have_constant do |const|
match do |owner|
(owner.is_a?(Class) ? owner : owner.class).const_defined?(const)
end
end
有关自定义匹配器的更多信息,请参阅http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers。
HTH,大卫
另一种简单地确保定义常量的选项——不用担心它是用什么定义的:
it 'has a WHATEVER constant' do
expect(SomeClass::WHATEVER).not_to be_nil
end
对尝试测试常量已定义的任何人的警告:如果您的代码在定义类时引用了未定义的常量,那么您的规范将在测试之前崩溃。
这会让你相信
expect { FOO }.to_not raise_error
未能捕获 NameError,因为您将得到一个很大的堆栈跟踪,而不是一个很好的“预计不会引发错误,但引发了 NameError”。
在巨大的堆栈跟踪中,很难注意到您的测试实际上在第 1 行崩溃:requre "spec/spec_helper" 因为您的整个应用程序在进入实际测试之前无法加载。
如果您有动态定义的常量,例如由 ActiveHash::Enum 完成,然后您在另一个常量的定义中使用它们,就会发生这种情况。不要费心测试它们是否存在,如果其中一个规范未能定义,您的应用程序中的每个规范都会崩溃。
你可以使用
defined? YOUR_MODEL::FIXED_LIST
在 RSpec 2 中,我能够让它在一行中工作,如下所示:
it { subject.class.should be_const_defined(:MY_CONST) }
也就是说,检查类,而不是实例。
在我的模型中
class Role < ActiveRecord::Base
ROLE_ADMIN = "Administrador"
end
在我的 rspec
RSpec.describe Role, type: :model do
let(:fake_class) { Class.new }
describe "set constants" do
before { stub_const("#{described_class}", fake_class) }
it { expect(described_class::ROLE_ADMIN).to eq("Administrador") }
end
end