Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails rspec - how to check for a model constant?

How can I do something like:

it { should have_constant(:FIXED_LIST) }

In my model (active record) I have FIXED_LIST = 'A String'

It's not a db attribute or a method and I haven't been able to use responds_to or has_attribute to test for it (they fail). What can I use the to check for it. - btw I have the shoulda-matchers installed.

like image 280
Michael Durrant Avatar asked Jul 05 '12 03:07

Michael Durrant


3 Answers

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"

like image 92
dutchstrider Avatar answered Oct 14 '22 07:10

dutchstrider


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.

like image 10
RyanScottLewis Avatar answered Oct 14 '22 07:10

RyanScottLewis


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

like image 8
David Chelimsky Avatar answered Oct 14 '22 06:10

David Chelimsky