CB: I think that looks pretty good. Let's try it and see what happens! Let's replace the test_create method with your new one and rerun the test.

ruby test\functional\category_controller_test.rb

Figure 19

Paul: Hmm... It says there was an error in the line where we tested the flash object. I don't get it. I tested it exactly the same way the scaffolding tested assigns in the new method. What gives?

CB: The assigns hash is a little different from the others. It's a "historical" thing and, frankly, I have a bit of a problem remembering all the differences between the rules for accessing assigns versus the other hashes. I've found that in most cases I can get by with just remembering one. For assigns I use parentheses, and for the others I use the standard hash notation, which is brackets. Just change...

assert_not_nil flash(:notice)

to

assert_not_nil flash[:notice]

and I think we'll be fine. Try it again.

Figure 20

Paul: Now that's more like it!

CB: Yep. You're definitely on a roll! How 'bout taking a look at the rest of the test case and the category controller and tell me what you see.

Paul: OK. Let me just start at the top. We've already covered the index method. But we haven't talked at all about this next section in the Category controller. I've got an inkling of what it does, but I don't understand how it does it. What throws me is that it doesn't have the same format as all the other methods. All the others are blocks that begin with def method_name and end with end. This is just standing there all by itself.

Figure 21

CB: My bad. I should have brought that up myself. Rails has a group of methods that are called before_ filters. They're a little like the validations we used in the models, but these work in the controllers. The reason they're called before_ filters is that they are examined before every method invocation. According to the official documentation (at api.rubyonrails.org), the verify method "is essentially a special kind of before_ filter." What this is telling Rails is that before the destroy, create, or update methods are called, it needs to examine the request parameters and verify that the request type is a POST. If an attempt is made to invoke any of these methods with any other request type, the request should be directed to the list method. As far as adding a specific test method for this, I could go either way. The way they stand right now, if it somehow got lost our existing tests would let us know because they're testing for the view that's used to render the method they're testing. On the other hand, with a specific test for this, if the verify did get lost, we'd have a specific test that might point us to the problem more quickly. I'll leave it up to you.

Paul: OK. I'll think about that. Moving on... the list method creates an instance variable we're not testing for: @category_pages. So we need to add that to the test_list method.

Figure 22

The test_show method contains a test we haven't covered yet: assert_assigns (:category).valid?. I don't understand that, but since it's an extra test rather than a missing test let's come back to it in a minute.

Figure 23

We've already covered the new and create methods so we're OK on those. The test_edit method has that same new assertion as the test_show method, so we'll come back to that too. The test_update method is only testing the success path so I'm thinking it needs the same treatment we gave test_create. And lastly, the test_destroy method uses the exception-trapping assertions in a way I haven't seen before so we'll need to talk about that before I know if we need anything more there. Did I miss anything?

CB: Not that jumps out at me. Good job! OK, you want to go over those assertions we haven't covered yet?

CB: What that's doing is running the validations in our model on the data being pulled out of the database. For performance reasons, when the fixtures get loaded the data in them isn't being run through the our model validations. So it's possible that we're loading data for our tests via our fixtures that our app wouldn't allow. This assertion is an example of how we might tackle the problem of making sure the data we use in our fixtures continues to be the right stuff as we grow our app. Right now I don't see us needing to make much fuss about it since we're still real early in the process, but it's something I'd like you to keep in the back of your mind. We might need you to figure out a good strategy for this if we end up with a lot of fixtures.