rails rspec - how to check for a model constant?

It reads a little silly, but:

describe MyClass do

  it { should be_const_defined(:VERSION) }

end

The reason is that Rspec has "magic" matchers for methods starting with be_ and have_. For example, it { should have_green_pants } would assert that the has_green_pants? method on the subject returns true.

In the same fashion, an example such as it { should be_happy } would assert that the happy? method on the subject returns true.

So, the example it { should be_const_defined(:VERSION) } asserts that const_defined?(:VERSION) returns true.


Based on David Chelimsky's answer I've got this to work by slightly modifying his code.

In a file spec/support/utilities.rb (or some other in spec/support) you can put:

RSpec::Matchers.define :have_constant do |const|
  match do |owner|
    owner.const_defined?(const)
  end
end

Note the use of "RSpec::Matchers.define" in stead of "matchers"

This allows to test for constants in your specs, like:

 it "should have a fixed list constant" do
    YourModel.should have_constant(:FIXED_LIST)
 end

Note the use of "have_constant" in stead of "have_const"


Another option to simply make sure the constant is defined – not worrying about what it's defined with:

it 'has a WHATEVER constant' do
  expect(SomeClass::WHATEVER).not_to be_nil
end

If you want to say have_constant you can define a custom matcher for it:

matcher :have_constant do |const|
  match do |owner|
    owner.const_defined?(const)
  end
end

MyClass.should have_const(:CONST)

If you're trying to use the one-liner syntax, you'll need to make sure the subject is a class (not an instance) or check for it in the matcher:

matcher :have_constant do |const|
  match do |owner|
    (owner.is_a?(Class) ? owner : owner.class).const_defined?(const)
  end
end

See http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers for more info on custom matchers.

HTH, David