Posted on February 27, 2007
How do you go about spec’ing model associations?
There’s an idea on the rspec mailing list.
However, I kind of like using reflect_on_association. Let’s say we have the following model:
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
has_many :images
has_many :inventories
belongs_to :designer
end
Then my context and specifications might look like:
context "Product model" do
specify "should respond to inventories" do
Product.reflect_on_association(:inventories).should_not_be_nil
end
specify "should respond to categories" do
Product.reflect_on_association(:categories).should_not_be_nil
end
specify "should respond to images" do
Product.reflect_on_association(:images).should_not_be_nil
end
specify "should respond to designer" do
Product.reflect_on_association(:designer).should_not_be_nil
end
end
This will catch the situation where an association definition is removed or changed.
Filed under: Rspec'ing |
Tagged with: associations model rails rspec |
Posted on February 26, 2007
I’ve been using rspec for a few months now, and I really like it. I recommend trying it out if you haven’t.
I figure it might be nice to share how I organize controller specs, and get some feedback on how others might organize their specs. I like having one test per specification like so:
specify "should redirect to new session url" do
response.should_redirect_to new_session_url
end
I also like calling the controller action in the setup method.
setup do
... any necessary setup info
post :update, :id => model, :model => params
end
Here’s what a context might look like in all its glory.
context "Create with a valid product and authenticated user" do
include ProductsControllerSpecHelper
controller_name :products
setup do
@product = mock(:product, :null_object => true)
Product.stub!(:new).and_return(@product)
@product.should_receive(:save!).and_return(true)
@product.should_receive(:categories).and_return([])
authenticate_user_mock
post :create, :product => valid_product_attributes
end
specify "should redirect to edit" do
response.should_redirect_to edit_product_url(@product)
end
specify "should assign product" do
assigns[:product].should_not_be_nil
end
end
Filed under: Rspec'ing |
Tagged with: controller rails rspec |
Posted on February 12, 2007
I've been using rspec for testing rails apps for about a month now. However, I hadn't tried to spec out the views. I decided to starting specing out the views today, and ran into a small obstacle.
I am currently using restful authentication plugin and I have snippets in my view like:
<% if logged_in? %>
....
<% end %>
Everything is good, until I tried to write my first view test. Calling:
render "controller/template"
I received a missing method error on "logged_in?". The problem is that rspec views are tested in isolation from the controller. This means my include AuthenticatedSystem in the application controller doesn't get loaded and that's where the "logged_in?" method is mixed in.
I did find out that the application_helper.rb and <controller>_helper.rb (where <controller> is the current controller associated with the template being tested) get loaded, so I could define the "logged_in?" method in either of the two helper classes. But the problem with that is that I would have "logged_in?" defined in a couple of places just to run my rspecs.
Digging around in the rspec for rails code base, I found that you can get access to the controller via @controller and the template via @controller.template.
Then a light came on! I could stub out the call to logged_in? on the template like so:
@controller.template.stub!(:logged_in?).and_return(true)
After doing that, everything worked fine. I also found it came in handy for stubbing out other template calls.
Filed under: Rail Views Rspec'ing |
Tagged with: mock rails views rspec template |