我怎麼可以這樣做:rails rspec - 如何檢查模型常量?
it { should have_constant(:FIXED_LIST) }
在我的模型(活動記錄)我有FIXED_LIST = 'A String'
這不是一個數據庫屬性或方法,我一直無法使用responds_to
或has_attribute
測試它(他們失敗)。我可以用什麼來檢查它。 - 順便說一句,我已安裝了應用程序匹配器。
我怎麼可以這樣做:rails rspec - 如何檢查模型常量?
it { should have_constant(:FIXED_LIST) }
在我的模型(活動記錄)我有FIXED_LIST = 'A String'
這不是一個數據庫屬性或方法,我一直無法使用responds_to
或has_attribute
測試它(他們失敗)。我可以用什麼來檢查它。 - 順便說一句,我已安裝了應用程序匹配器。
基於大衛赫利姆斯基的答案我有這個通過稍微修改了代碼工作。
在文件規範/支持/ utilities.rb(或一些其他的規格/支),你可以把:
RSpec::Matchers.define :have_constant do |const|
match do |owner|
owner.const_defined?(const)
end
end
注意使用「的RSpec :: Matchers.define」中的「代替匹配器」
這使得以測試你的規格常量,如:
it "should have a fixed list constant" do
YourModel.should have_constant(:FIXED_LIST)
end
注意使用‘have_constant’以代替‘have_const’
你可以使用
defined? YOUR_MODEL::FIXED_LIST
如果你想說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, 大衛
我在哪裏放置匹配代碼? –
我試着把它放在spec/support/matchers中,但是我在匹配代碼的第一行得到了'main:Object(NoMethodError)'的'未定義方法'matcher' –
我做了[一個要點](https:// gist .github.com/redconfetti/6356551)用我設計的解決方案。 –
它讀取有點傻,但是:
describe MyClass do
it { should be_const_defined(:VERSION) }
end
的原因是Rspec的有開始be_
和have_
方法「神奇」的匹配。例如,it { should have_green_pants }
會斷言subject
上的has_green_pants?
方法返回true
。
以相同的方式,例如it { should be_happy }
的示例會斷言subject
上的happy?
方法返回true
。
因此,示例it { should be_const_defined(:VERSION) }
聲明const_defined?(:VERSION)
返回true
。
我正在使用RSpec 2.14.1,無論我嘗試哪種方式,都無法使其工作。哪個(主要)版本的RSpec你是否得到這個工作?我總是以'NoMethodError ...未定義的方法'const_defined?'錯誤結束。 – Todd
抱歉太晚了@RyanScottLewis,不能編輯我上面的評論。我得到它的工作如下:'it {subject.class.should be_const_defined(:MY_CONST)}'。這個問題大概是因爲它檢查了「subject」而不是Class。 – Todd
如果你正在描述你的課程(沒有引號),這應該按照rspec 3.4的規定工作。 – randallreedjr
對試圖測試常量的任何人發出警告:如果您的代碼在定義類時引用了未定義的常量,那麼您的規格將在他們進行測試之前崩潰。
這可能會導致您認爲
expect { FOO }.to_not raise_error
未能趕上NameError,因爲你會得到一個很大的堆棧跟蹤,而不是一個很好的「預計不會引發錯誤,但上調NameError。 「
在巨大的堆棧跟蹤中,可能很難注意到您的測試實際上在第1行崩潰:請求「spec/spec_helper」,因爲您的整個應用程序在到達實際測試之前未能加載。
如果您有動態定義的常量(例如ActiveHash :: Enum完成),然後在另一個常量的定義中使用它們,則會發生這種情況。不要打擾他們存在的測試,如果你的應用程序中的一個未能定義,你的應用程序中的每個規格都會崩潰。
在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
我試着'它{應當界定?(:EMPTY_TABLE)}'但得到'未定義的方法'比賽」 for「expression」:String' –
'應該定義什麼?(MODEL_NAME :: EMPTY_TABLE)'? – xdazz
它{應該定義?(ActivityDetail :: EMPTY_TABLE)}給了未定義的方法'匹配?'爲「常量」:字符串 –