2

Hi,

I am trying to DRY up some of my specs. I extracted an Assertion class that does a couple of shoulds ... but most of the RSpec expectation magic is not working anymore.

I'll try to construct a simple example, to show my problem.

The object under test:

class Foo
  def has_bar?; true; end
end

My assertion class:

class MyAssertions
  def self.assert_everything_is_ok
    @foo = Foo.new
    @foo.has_bar?.should == true  # works!
    @foo.has_bar?.should be_true  # undefined local variable or method `be_true`
    @foo.should have_bar          # undefined local variable or method `have_bar`
  end
end

My spec:

it "tests something" do
  @foo = Foo.new
  @foo.should have_bar                # works!
  MyAssertion.assert_everything_is_ok # does not work, because of errors above
end

Why can I not use the syntactic sugar of rspec expectations in my plain old ruby object?

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
DiegoFrings
  • 3,043
  • 3
  • 26
  • 30

2 Answers2

2

After some more trying I came up with this solution:

class MyAssertions
  include RSpec::Matchers

  def assert_everything_is_ok
    @foo = Foo.new
    @foo.has_bar?.should == true  # works!
    @foo.has_bar?.should be_true  # works now :)
    @foo.should have_bar          # works now :)
  end
end

The trick was to include the RSpec::Matchers module. And I had use instance methods instead of class methods.

DiegoFrings
  • 3,043
  • 3
  • 26
  • 30
2

A more 'RSpec-like' way to do this is with a custom matcher:

RSpec::Matchers.define :act_like_a_good_foo do
  match do
    # subject is implicit in example
    subject.has_bar?.should == true
    subject.should be_true  # predicate matchers defined within RSpec::Matchers
    subject.should have_bar
  end
end

describe Foo do
  it { should act_like_a_good_foo }
end
zetetic
  • 47,184
  • 10
  • 111
  • 119
  • That's nice. Thanks for pointing that out. It suits the simplified example I posted pretty well. However my real-world problem is more complicated and features page-objects and behavior-objects that need to access the Matchers (outside of the spec itself). – DiegoFrings Apr 11 '14 at 13:46