advertisement

Print

Cookin' with Ruby on Rails - More Designing for Testability
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

Looking good! Looks like we're ready to move on to the category controller test. Let's go ahead and fix the reference to the :first fixture before we do. In the setup method, change...

@first_id = recipies(:first)

to

@first_id = recipes(:one)

And since we know that recipes need to have a title and to be assigned to a category for our validations to work, let's go ahead and change the line in the test_create method to avoid that error. Change...

post :create, :recipe => {}

to

post :create, :recipe => {:title => "new recipe", :category_id => 1}

And now let's give our recipe controller test a run to see where we are on that.

ruby test\functional\recipe_controller_test.rb

our first run of the recipe controller test
Figure 32

Paul: I'd say that's a pretty good start ;-)

CB: Gotta agree with you there, Paul ;-) You want to take us through the changes we need to make?

Paul: Sure. I'll just start at the top again. The test_index method looks OK. I'm going to copy over the test_verify_gets_are_safe method from the category controller test.

def test_verify_gets_are_safe
   get :destroy
   assert_redirected_to :action => 'list'
   get :create
   assert_redirected_to :action => 'list'
   get :update
   assert_redirected_to :action => 'list'  
end

We changed the list method in the recipe controller so it would filter for a category, though, so it's different from the list method in the category controller.

the list methods are different
Figure 33

I think we need to beef up our test method here. Here's what we've got now.

scaffolded test_list method for recipe_controller_test
Figure 34

Paul: This test doesn't pass in anything for the category_id param so that takes care of the first branch in the list method. I think we just need to do a second pass in here passing in the category_id and making sure the same assertions still pass. It doesn't make sense to me to try to make sure that only the right records were returned, especially not in the controller test. If we were going to test for that, I'd say we'd need to do it in the Unit tests. What do you think?

CB: Sounds good to me.

Paul: Cool. So, I'm going to replace the test_list method with one I'll name test_list_all_and_filtered.

def test_list_all_and_filtered
   get :list
   assert_response :success
   assert_template 'list'
   assert_not_nil assigns(:recipes)
   get :list, :category_id => '1'
   assert_response :success
   assert_template 'list'
   assert_not_nil assigns(:recipes)
end

The test_show and test_new methods are OK, but the test_create needs the same treatment we gave it in the category controller test. So I'll replace test_create with test_create_success_and_failure. pretty much just like we did before, except for the variable names. We just have to remember that recipes need both a title and the foreign key to save successfully.

def test_create_success_and_failure
   num_recipes = Recipe.count
   post :create, :recipe => {:title => "new recipe", :category_id => 1}
   assert_response :redirect
   assert_redirected_to :action => 'list'
   assert_not_nil flash[:notice]
   assert_equal num_recipes + 1, Recipe.count

   num_recipes = Recipe.count
   post :create, :recipe => {:title => ""}
   assert_response :success
   assert_template 'new'
   assert_equal num_recipes, Recipe.count
end

For the test_update method, we need to make sure invalid updates generate errors, just like we did in the category controller. So we'll add the same two lines to the end of the method.

post :update, :id => @first_id, :title => ''
assert :redirect

Which brings us to the test_destroy method which, on the same reasoning we came to in the category controller, seems to be OK for the moment.

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

Next Pagearrow