Wrong with mock_model in rspec? - ruby-on-rails

Here is the rspec code for testing show in customers controller:
it "'show' should be successful" do
#category = Factory(:category)
#sales = Factory(:user)
#customer = Factory(:customer, :category1_id => category.id, :sales_id => sales.id)
category = mock_model('Category')
sales = mock_model('User')
customer = mock_model(Category, :sales_id => sales.id, :category1_id => category.id)
get 'show' , :id => customer.id
response.should be_success
end
Here is the error in rspec:
CustomersController GET customer page 'show' should be successful
Failure/Error: get 'show' , :id => customer.id
ActiveRecord::RecordNotFound:
Couldn't find Customer with id=1003
# c:in `find'
# ./app/controllers/customers_controller.rb:59:in `show'
# ./spec/controllers/customers_controller_spec.rb:50:in `block (3 levels) in <top (required)>'
The rspec test passes with the real record created by Factory (see #ed in rspec code)
What's wrong with the mock? Thanks.

The spec is failing inside the controller's action which doesn't know anything about your mocks unless you told it explicitly.
Add this to your spec, before the get statement.
Customer.should_receive(:find).and_return(customer)

Related

Rspec controller post request to render different partials

I am trying to write a controller spec to test that the right partial is rendering after a post request.
Here is the controller method being posted to:
def lookup
#guest = Guest.where("mobile_number = ?", params[:lookup_mobile_phone_number]).first_or_initialize do |g|
g.mobile_number = params[:lookup_mobile_phone_number]
end
if #guest.new_record?
#visit = Visit.new(hotel_id: params[:hotel_id])
render partial: "guests/form"
else
#visit = Visit.new(guest_id: #guest.id, hotel_id: params[:hotel_id])
render partial: "visits/form"
end
end
Here is the spec/controllers/guests_controller_spec.rb I wrote that is failing:
RSpec.describe GuestsController, :type => :controller do
describe "#lookup" do
render_views
let!(:returning_guest) { create(:test_guest) }
context "when guest is already registered with hotel" do
it "renders visits/form" do
post :lookup, :guest => { :lookup_mobile_phone_number => "5553331212"}
expect(response).to render_template(:partial => 'visits/form')
end
end
end
end
Here is the factory I'm using for :test_guest
FactoryGirl.define do
factory :test_guest, :class => 'Guest' do
name 'Jack Guest'
mobile_number '5553331212'
end
end
This is the response I am getting when the test fails
1) GuestsController#lookup when guest is already registered with hotel renders visits/form
Failure/Error: expect(response).to render_template(:partial => 'visits/form')
expecting partial <visits/form> but action rendered <["shared/_hotel_agent_name", "_hotel_agent_name", "guests/_form", "_form"]>.
Expected {"shared/_hotel_agent_name"=>1, "_hotel_agent_name"=>1, "guests/_form"=>1, "_form"=>1} to include "visits/form".
# ./spec/controllers/guests_controller_spec.rb:16:in `block (4 levels) in <top (required)>'
I've been hacking away at this a for a few days now, trying different approaches found on here with no luck. Any help would be much appreciated :)
You send
post :lookup, :guest => { :lookup_mobile_phone_number => "5553331212"}
but in controller, you use
params[:lookup_mobile_phone_number]
not
params[:guest][:lookup_mobile_phone_number]
So to fix it, according to your controller, do
post :lookup, :lookup_mobile_phone_number => "5553331212"

rails rspec render_template matcher

I have this projects controller brief action.
projects_controller.rb
def brief
##project before_filter_da ataniyor
if #project.user_allowed_to_view_brief?(current_user)
#brief_notes = #project.brief_notes.order(:id)
#project_files = #project.project_files
render :action => :written_brief if #project.project_type.brief_template == :written
else
render :action => :hidden_brief
end
end
And this is my projects_controller_spec.rb file
context 'get :brief' do
it 'should be loaded successfully' do
sign_in #creative
#project.stub(:user_allowed_to_view_brief?).with(#creative).and_return(false)
get :brief, :id => #project.to_param
response.should render_template("hidden_gallery")
end
end
and When I run this test, I encounter the error like that.
Failure/Error: response.should have_rendered("hidden_gallery")
expecting <"hidden_gallery"> but rendering with <"shared/_project_title, shared/_project_header, shared/_project_buttons, shared/_messages, projects/_brief, projects/brief, shared/_header, shared/_footer, layouts/application">
# ./spec/controllers/projects_controller_spec.rb:63:in `block (3 levels) in <top (required)>'
I think that the last line of your spec should instead read:
response.should render_template("hidden_brief")

Rspec failing in rails

I am receiving the following errors for my Rspec test in rails
1) MoviesController searching for similar movies should find the similar movies by director
Failure/Error: get :similar, {:id => "1"}
ActiveRecord::RecordNotFound:
Couldn't find Movie with id=1
# ./app/controllers/movies_controller.rb:63:in `similar'
# ./spec/controllers/movies_controller_spec.rb:16:in `block (3 levels) in <top (required)>'
2) MoviesController searching for similar movies should select the Similiar Movies template for rendering
Failure/Error: get :similar, {:id => "1"}
ActiveRecord::RecordNotFound:
Couldn't find Movie with id=1
# ./app/controllers/movies_controller.rb:63:in `similar'
# ./spec/controllers/movies_controller_spec.rb:22:in `block (3 levels) in <top (required)>'
3) MoviesController searching for similar movies it should make the results available to the template
Failure/Error: get :similar, {:id => "1"}
ActiveRecord::RecordNotFound:
Couldn't find Movie with id=1
# ./app/controllers/movies_controller.rb:63:in `similar'
# ./spec/controllers/movies_controller_spec.rb:29:in `block (3 levels) in <top (required)>'
And this is my controller method that is causing it to fail:
def similar
#movie = Movie.find(params[:id])
#movies = Movie.find_all_by_director(Movie.find_by_id(params[:id])[:director])
if #movies.count <= 1
redirect_to movies_path
flash[:notice] = "'#{#movie.title}' has no director info"
end
I can't understand why this test keeps failing with the same error. Any help would be much appreciated
Below are the tests
describe MoviesController do
describe 'searching for similar movies' do
before :each do
#fake_movies = [mock('Movie'), mock('Movie')]
#fake_movie = FactoryGirl.build(:movie, :id => "1", :title => "Star Wars", :director => "George Lucas")
end
it 'should follow the route to the similar movies by director page' do
assert_routing('movies/1/similar', {:controller => 'movies', :action => 'similar', :id => '1'})
end
it 'should find the similar movies by director' do
Movie.should_receive(:find_by_id).with("1").and_return(#fake_movie)
Movie.should_receive(:find_all_by_director).with(#fake_movie.director).and_return(#fake_movies)
get :similar, {:id => "1"}
end
it 'should select the Similiar Movies template for rendering' do
Movie.should_receive(:find_by_id).with("1").and_return(#fake_movie)
Movie.should_receive(:find_all_by_director).with(#fake_movie.director).and_return(#fake_movies)
get :similar, {:id => "1"}
response.should render_template('similar')
end
it 'it should make the results available to the template' do
Movie.should_receive(:find_by_id).with("1").and_return(#fake_movie)
Movie.should_receive(:find_all_by_director).with(#fake_movie.director).and_return(#fake_movies)
get :similar, {:id => "1"}
assigns(:movies).should == #fake_results
end
end
end
FactoryGirl is setup as follows:
FactoryGirl.define do
factory :movie do
title 'Star Wars'
director 'George Lucas'
end
end
The spec calls Factory.build. That does not persist the object to the database. You'll want to use Factory.create to allow Movie.find to work.

How to rspec 'show' 1-to-many associated controller in rails 3.1

Have 2 models: lease_booking and lease_log. A lease_booking has_many lease_log and, a lease_log belongs_to a lease_booking. In routes.rb it is:
resources :lease_bookings do
resources :lease_logs
end
There is an error for rspec 'show':
6) LeaseLogsController show should display log content
Failure/Error: get 'show', :lease_booking_id => booking.id, :id => log.id
ActionView::Template::Error:
undefined method `name' for nil:NilClass
# ./app/views/lease_logs/show.html.erb:23:in `_app_views_lease_logs_show_html_erb___751480249_50095404'
# ./spec/controllers/lease_logs_controller_spec.rb:87:in `block (3 levels) in <top (required)>'
The rspec 'show' code is:
it "should display log content" do
booking = Factory(:lease_booking)
log = Factory(:lease_log, :lease_booking_id => booking.id)
get 'show', :lease_booking_id => booking.id, :id => log.id
response.should be_success
end
The controller code is:
def show
#lease_booking = LeaseBooking.find(params[:lease_booking_id])
#lease_log = #lease_booking.lease_log.find(params[:id])
end
Any idea about the error? Thanks.

following ruby.railstutorial.org/ and getting failing test

I am using Ruby 1.9.2 and Rails 3.0.3
I am consistently getting failing test errors within this tutorial such as:
1) UsersController GET 'show' should show the user's micropost
Failure/Error: get :show, :id => #user
undefined method `model_name' for NilClass:Class
# ./app/views/users/show.html.erb:10:in `_app_views_users_show_html_erb__2659465448390875355_2173812560_4463455946834160058'
# ./spec/controllers/users_controller_spec.rb:39:in `block (3 levels) in <top (required)>'
show.html.erb:10 is:
<% unless #user.microposts.empty? %>
<table class="microposts" summary="User microposts">
<%= render #microposts %> #line 10
</table>
<%= will_pagination #microposts %>
<% end %>
users_controller_spec.rb:39 is:
describe "GET 'show'" do
before(:each) do
#user = Factory(:user)
end
.
.
.
it "should show the user's micropost" do
mp1 = Factory(:micropost, :user => #user, :content => "Foo bar")
mp2 = Factory(:micropost, :user => #user, :content => "Baz quux")
get :show, :id => #user
response.should have_selector("span.content", :content => mp1.cntent)
response.should have_selector("span.content", :content => mp2.content)
end
and my app/controllers/users_controller.rb where is defines micropost is:
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(:page => params[:page])
#title = #user.name
end
any help would be greatly appreciated. I have a total of 14 errors. My other errors are about
Failure/Error: get :edit, :id => #user
#controller is nil: make sure you set it in your test's setup method.
and
Failure/Error: test_sign_in(wrong_user)
undefined method `sign_in' for nil:NilClass
I am also using Factory as a test sign in. Im not sure if this could be a problem. I mention this because some of the errors are:
9) authentication of edit/update pages GET 'index' for signed-in users should have the right title
Failure/Error: #user = test_sign_in(Factory(:user))
Validation failed: Email has already been taken
# ./spec/controllers/users_controller_spec.rb:222:in `block (4 levels) in <top (required)>'
If you need to see anymore code please let me know.
If someone could direct me to a place to learn more about debugging, that would be a big help as well.
For error 1 try checking your filenames for spelling and case.
For error 9 try double checking which do..end you paste your code into.
Working code for the tutorial can be found here https://github.com/railstutorial

Resources