RSpec and Mocha; lesson learned

Journal entry
September 11, 2008

During development of a small Ruby application today I ran into a minor issue with RSpec and Mocha. Earlier today, I was developing a small Ruby application, trying out RSpec instead of the usual Test::Unit, using Mocha for my stubbing and mocking needs.

Unfortunately, things didn’t go as I expected them to today. Imagine starting out with the following (contrived) examples:

describe 'Car' do
  describe "when starting" do
    before :each do
      @car = Car.new
    end
    it "should insert key" do
      @car.expects(:insert_key)
      @car.start
    end    
    it "should turn key" do
      @car.expects(:turn_key)
      @car.start
    end
  end
end

That’s the behaviour I want, now let’s add some code to make the specs green.

class Car
  def start
  end
end

The above is a nice scaffold for our full implementation, but there is one problem. The specs actually pass! Without any actual code, the expectations are apparently being triggered. This is obviously not correct, and it was driving me mildly crazy. Fortunately, a bit of Googling led me to a blog post who gave me the solution.

While RSpec has its own, built-in mocking framework it doesn’t mind stepping down and leave the mocking to Mocha - but you have to tell it to do so:

Spec::Runner.configure do |config|
  config.mock_with :mocha
end

With the above added to my specs they properly fail, yay! Hopefully that’ll teach me to RTFM.

Categories
Selling out
Did you know?
Jakob is an independent webdesigner/developer who builds awesome stuff for the web. You can hire him to build awesome stuff for you.

Comments and Trackbacks

Matthijs Langenberg September 14, 2008

Jakob, I really don’t think it’s a good idea to mock interactions within the same object. I usually only try to test the behaviour between objects. For example:

describe 'Car' do describe "when starting" do before :each do @key = Key.new (or mock if Key.new requires too much setup code) @car = Car.new(@key) end it "should insert key" do @key.expects(:insert) @car.start end it "should turn key" do @key.expects(:turn) @car.start end end end

What do you think?

Matthijs Langenberg September 14, 2008

That got messed up pretty much, please see http://gist.github.com/10764.
Great you are doing BDD, Jakob.

Jakob S September 15, 2008

I think coming up with bulletproof code examples is hard ;)

I am not entirely sure I agree with your point. Inter-object interaction should obviously be specced, but I don’t see why intra-object interaction (intraaction?) shouldn’t?

Anyways, it’s all besides the point. Even with your code RSpec still needs to be told that it’s using Mocha for stubbing as I mention above.

Commenting on this entry has been closed.

... but if you're a dirty spambot, feel free to post a comment here anyways.