Mike Clark's - How Would You Test This 18 Sep 2007
Below is my rspec answer to Mike Clark’s recent post “How Would You Test This”:http://www.clarkware.com/cgi/blosxom/2007/09/08#TestingControllers which challenges people to post their own solution to how you’d test his MenuitemsController.

One thing Mike doesn’t mention about the frustration that people have with testing controllers is testing that testing controllers requires you to test your view associated with it (unless you are only redirecting).

There are ways around testing views, but most install a custom hack or installing a third party plugin or framework like rspec, Test::Rails or view_test.

Since Mike didn’t include any views in his original post I haven’t provided any tests for them in this post.

require File.dirname(__FILE__) + '/../spec_helper'

def do_post(attributes)
  post :create, :menu_item => attributes
end

describe MenuItemsController, 'Creating a new menu item (success)' do

  before do
    attributes = {'name' => "Enchilada", 'price' => 4.99}
    @menu_item = mock_model(MenuItem)
    MenuItem.should_receive(:new).with(attributes).once.and_return(@menu_item)
    @menu_item.should_receive(:save).with().once.and_return(true)

    do_post attributes
  end

  it 'redirects to index' do
    response.should redirect_to(menu_items_url)
  end

  it 'assigns @menu_item' do
    assigns[:menu_item].should be(@menu_item)
  end

  it 'sets the flash notice' do
    flash[:notice].should_not be(nil)    
  end
end

describe MenuItemsController, 'Creating a new menu item (failure)' do

  before do
    attributes = {'name' => "Enchilada", 'price' => 4.99}
    @menu_item = mock_model(MenuItem)
    MenuItem.should_receive(:new).with(attributes).once.and_return(@menu_item)
    @menu_item.should_receive(:save).with().once.and_return(false)

    do_post attributes
  end

  it 'renders new template on failed save' do
    response.should be_success
    response.should render_template('new')
  end

  it "assigns @menu_item" do
    assigns[:menu_item].should be(@menu_item)
  end

  it "not set the flash notice" do
    flash[:notice].should be(nil)      
  end

end

blog comments powered by Disqus