Routing rspec with nested routes

Problem

You would like to add a routing rspec test in your rails application that tests for a nested route.
So while you have something like the following in your config/routes.rb file:

namespace :admin do
  resources :users do
    resources :audits, only: [:index]
  end
end

you want to add the following test for your route:

expect(get: '/admin/users/:user_id/audits').to route_to(controller: 'admin/audits', action: 'index')

but you are getting an error like the following:

The recognized options <{"controller"=>"admin/audits", "action"=>"index", "user_id"=>":user_id"}> did not match <{"controller"=>"admin/audits", "action"=>"index"}>, difference:.
       --- expected
       +++ actual
       @@ -1 +1 @@
       -{"controller"=>"admin/audits", "action"=>"index"}
       +{"controller"=>"admin/audits", "action"=>"index", "user_id"=>":user_id"}

Solution

You will need to change your rspec to the following using any number for the user_id:

expect(get: '/admin/users/42/audits').to route_to(controller: 'admin/audits', action: 'index', user_id: '42')

Solution adapted from here

SSL testing in rspec

Problem
You have added the force_ssl option in your rails application, and the rspec tests fail with a redirection as ssl is required in the test evnironment.

Solution
Using a solution provided here you can add the following to your rspec test to ensure that ssl is used and the tests pass:

before(:each) do
  request.env["rack.url_scheme"] = "https"
end

Replacing mock objects with factory girl in controller rspecs

Problem

You would like to use factory_girl instead of the mock models described in the RSpec book (Behaviour Driven Rails – Rails Controllers – Controller specs).

 

Solution

Make sure that you use let! instead of let and have the following:

 

require 'spec_helper'

describe MessagesController do
  describe "POST create" do
    let!(:message) { Factory.create(:message) }
    
    before do 
      Message.stub(:new).and_return(message)
    end
    
    it "creates a new message" do
      Messagee.should_receive(:new).with("text" => "a quick brown fox").and_return(message)
      post :create, :message => {"text" => "a quick brown fox"}
    end
    
    it "saves the message" do
      message.should_receive(:save)
      post :create
    end

    it "redirects to the Messages index" do
      post :create
      response.should redirect_to(:action => "index")
    end
  end
end

Testing associations in Rspec

Problem
You would like to test your model associations in an RSpec model spec, to make sure that they are correctly set up.

Solution
After some Google searching and coming across this article here, ended up using the second method described there with the reflect_on_association method, as it doesn’t need the inclusion of another gem.
So for example to to test multiple has_many or belongs_to associations in your model rspec you could use something like:
context "check associations" do
# belongs_to associations
%w{bel_to1 bel_to2}.each do |bt|
it "should belong to #{bt}" do
m = Model.reflect_on_association(:"#{bt}")
m.macro.should == :belongs_to
end
end
# has_many associations
%w{has_many1 has_many2 has_many3}.each do |hm|
it "should have many #{hm}" do
m = Model.reflect_on_association(:"#{hm}")
m.macro.should == :has_many
end
end
end

Couldn’t find ‘rspec’ generator – Rails 2.3.10

Problem
You are trying to use rspec with Ruby on Rails 2.3.10, but although you install the rspec and rspec-rails gems you get the following error when you try to run script/generate rspec
Couldn't find 'rspec' generator

Solution
It turns out that there is a problem with the versions used, so by following the instructions for Rails >= 2.3.10 from here, you should be able to install the plugins and use rspec:
ruby script/plugin install git://github.com/dchelimsky/rspec.git -r 'refs/tags/1.3.1'
ruby script/plugin install git://github.com/dchelimsky/rspec-rails.git -r 'refs/tags/1.3.3'
ruby script/generate rspec

where the last tag (1.3.3) should be the latest tag for each gem.

*** NOTE *** If you get an error like :
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.map (NoMethodError)

uncomment the following line (line 11) from features/support/env.rb:
require 'cucumber/rails/rspec'
and run rake cucumber again.

Adding Webrat, Cucumber and RSpec to a new Rails 3 project

Problem

You would like to start using BDD in a new Ruby on Rails 3 application, and would like to install Webrat, Cucumber and RSpec to your project.

Solution

Follow the steps below (taken from the RSpec Book), for creating a new Rails 3 application and adding the necessary testing frameworks:

  1. Create your new ruby on rails application: rails new my_app
  2. Go to your new application directory: cd my_app
  3. Edit your Gemfile to include the following:
    group :development, :test do
    gem "rspec-rails", ">= 2.0.0"
    gem "cucumber-rails", ">= 0.3.2"
    gem "webrat", ">= 0.7.2"
    end
  4. Use bundler to install all the gems and dependencies: bundle install
  5. Install the rspec files: script/rails generate rspec:install
  6. Install the cucumber files: script/rails generate cucumber:install
  7. Run the following and you shouldn’t be seeing any errors:
    rake db:migrate
    rake db:test:prepare
    rake spec
    rake cucumber