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
Where is the documentation for the post method (and other REST verbs)?
How does the object created by
MenuItem.any_instance.stubs(:valid?).returns(true)
get passed to the controller a开发者_如何转开发ction?
How is question 2 differ from directly passing params to the controller via the post method?
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.
You can find documentation for the test REST methods in the Rails docs
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 ofMenuItem
that's created in the context of your specs will returntrue
for thevalid?
method.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 returntrue
is the lower maintenance option when compared to passing all the params necessary to have your model returntrue
on its own.
精彩评论