self.send :notes
Random thoughts on life, technology & business in South East Asia

Simplifying BDD on has_many associations

My first Ruby on Rails post on this blog..

– another advantage of Fat Models Thin Controllers.

Consider

class Box < ActiveRecord::Base
  has_many :marbles
end

class BoxesController < ActionController::Base
  def show
    @box = Box.find(params[:box_id])
    @box.marbles.find(params[:id)])
  end
end

To test this using rspec, you write something like

describe BoxesController, "handling GET /boxes/1/marbles/2"
  def do_get
    get :show, :box_id => 1, :id => 2
  end
  it "should get the right marble" do
    @marble = mock_model(Marble)
    @marbles = mock_model(Array)
    @marbles.should_receive(:find).with("2").and_return(@marble)
    @box = mock_model(Box, :marbles => @marbles)
    Box.should_receive(:find).with("1").and_return(@box)
    do_get
  end
end

I think the @marbles part in the controller specs is misplaced and ugly. This behavior should be pushed into the model specs. So lets refactor by combining the collection (@marbles) and find method into find_marble:

class Box < ActiveRecord::Base
  has_many :marbles
  def find_marble(id)
    marbles.find(id)
  end
end
class BoxesController < ActionController::Base
  def show
    @box = Box.find(params[:box_id])
    @box.find_marble(params[:id)]
  end
end

This makes the controller specs:

describe BoxesController, "handling GET /boxes/1/marbles/2"
  def do_get
    get :show, :box_id => 1, :id => 2
  end
  it "should get the right marble" do
    @marble = mock_model(Marble)
    @box = mock_model(Box)
    @box.should_receive(:find_marble).with("2").and_return(@marble)
    Box.should_receive(:find).with("1").and_return(@box)
    do_get
  end
end

and model specs code:

describe Box do
  it "should find_marble" do
    @marble = mock_model(Marble)
    @marbles = mock_model(Array)
    @marbles.should_receive(:find).with("1").and_return(@marble)
    @box = mock_model(Box, :marbles => @marbles)
    @box.find_marble("1").should == @marble
  end
end

I feel that this is much cleaner. What do you think?

Advertisement

No Responses to “Simplifying BDD on has_many associations”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.