views:

311

answers:

2

I am doing some controller testing with RSpec and Mocha. Here is an example

describe MenuItemsController, "creating a new menu item" do
  integrate_views
  fixtures :menu_items

  it "should redirect to index with a notice on successful save" do
    MenuItem.any_instance.stubs(:valid?).returns(true)
    post 'create'
    assigns[:menu_item].should_not be_new_record
    flash[:notice].should_not be_nil
    response.should redirect_to(menu_items_path)
  end
end

I have a few questions regarding this example

  1. Where is the documentation for the post method (and other REST verbs)?

  2. How does the object created by

    MenuItem.any_instance.stubs(:valid?).returns(true)

    get passed to the controller action?

  3. How is question 2 differ from directly passing params to the controller via the post method?

+1  A: 

1.

For Post

For Get

For Put

For Delete

2.

It is not really passed. You are configuring your test case so that, given that a call to valid? is made by a MenuItem instance. Then your stub will be used and the result of this valid? check will be true. You are deciding what is going to be returned by this valid? call

3.

When you stub, when the test run, instead of executing the code normally, for this specific valid? on a MenuItem instance; your code won't try to determine if your menuItem is valid or not. It will just return the value you specified in your stubs. In your case true

Thus here you are not testing that your MenuItem instance returns true given a correct parameter but you are testing what is happening when your MenuItem instance returns true.

It might not be really useful for you here if you can easily set up a post with a parameter which will always result in a valid? == true for your MenuInstance item.

But for example when you have a piece of code which connects to a WebService, you can use a stub which returns Connection Unavailable to test what happens in your code when the Webservice is down.

Aurélien Bottazzini
+1  A: 
  1. You can find documentation for the test REST methods in the Rails docs

  2. The object is not passed to the controller, it is created by the controller. MenuItem.any_instance.stubs(:valid?).return(true) assures that any instance of MenuItem that's created in the context of your specs will return true for the valid? method.

  3. The main purpose for stubbing out methods is to isolate what you're testing. If you pass your params to the controller instead of stubbing out only the methods that you need to get your controller tested, you're now testing your controller and your model. Since you probably have your models spec'd out elsewhere, the duplication only serves to make your specs more complicated and fragile.

    Stubbing the valid? method to return true is the lower maintenance option when compared to passing all the params necessary to have your model return true on its own.

Baldu