Rspec not testing render, won't allow us to stub render action - ruby-on-rails

Rails 5.0.0.1
Rspec 3.5.4
Ruby 2.3.1
We have been trying to provide test coverage for our rails application. We have a rescue in a private method that Rspec is not reaching.
Rspec:
it 'returns 200 after 404 from GET #edit error' do
allow(controller).to receive(:getpackages).and_return(URI::InvalidURIError)
expect(response.code).to eq(200) # => covers the 200
expect(response).to render_template('errors/5xx') # => doesn't read
end
Rails:
private
def set_package
#package = PackageServices.getpackage params[:id]
rescue URI::InvalidURIError
render 'errors/5xx'
end
Error message:
expecting <"errors/5xx"> but rendering with <[]>
./spec/controllers/packages_controller_spec.rb:139:in `block (3 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'
We have tried to assert_template, tried to stub it using stub_template, installed a gem rails-controller-testing (not rspec), but we have run out of ideas and every google link is purple. Is this a bug in Rspec or are we going about it the wrong way?

I believe the stabbing was incorrect. Try the following code, it should work.
context 'URI is invalid' do
before do
allow(PackageServices).toreceive(:getpackage).and_raise(URI::InvalidURIError)
end
it 'returns 200 after 404 from GET #edit error' do
expect(response.code).to eq(200) # => covers the 200
expect(response).to render_template('errors/5xx') # => doesn't read
end
end

Related

RoR rspec-rails error NoMethodError: Undefined method ‘get’

everybody!
I am doing RoR requests test and I am getting this error:
Failures:
1) Users GET #index is a success
Failure/Error: before(:example) { get "/users" }
NoMethodError:
undefined method `get' for #<RSpec::ExampleGroups::Users::GETIndex:0x000055a33f143f60>
Did you mean? gets
gem
# ./spec/requests/users_spec.rb:6:in `block (3 levels) in <top (required)>'
My code is:
RSpec.describe 'Users', type: :request do
describe 'GET #index' do
before(:example) { get "/users" }
it 'is a success' do
expect(response).to have_http_status(:ok)
end
it "renders 'index' template" do
expect(response).to render_template(:index)
end
it "shows the rendered text 'Welcome to the Ruby on Rails Blog'" do
expect(response).to include('Welcome to the Ruby on Rails Blog')
end
end
end
I did not include require ‘rails_helper’ in the spec file, because when I do this I am getting this error
ChildProcess::MissingFFIError:
FFI is a required pre-requisite for Windows or posix_spawn support in the ChildProcess gem. Ensure the `ffi` gem is installed. If you believe this is an error, please file a bug at http://github.com/enkessler/childprocess/issues
ruby version => ruby 3.1.1p18
rails version => Rails 7.0.2.4
RSpec version => RSpec 3.11

How do we print response body in rspec

I am trying to write an rspec file for my meetings_controller.rb so as to check if the values returned from my database are correct.
When I go to localhost:3000/meeting.json, this is the result of my data from the database
my rspec file is trying to check if the correct values are returned.
I created a folder called controller under specs (after I have installed rspec)and have the file meeting_controller_spec.rb
require 'rails_helper'
# Change this ArticlesController to your project
RSpec.describe MeetingsController, type: :controller do
describe "GET #index" do
# check index
it "returns a success response" do
get :index
puts response.body
expect(response).to have_http_status(:ok)
end
end
end
I tried to print the response body but nothing is returning. Is there a way to do this?
(base) adam-a01:reservation adrianlee$ rspec
.
Finished in 0.0892 seconds (files took 12.15 seconds to load)
1 example, 0 failures
Btw this is my meeting_controller.rb
class MeetingsController < ApplicationController
before_action :set_meeting, only: [:show, :edit, :update, :destroy]
# GET /meetings
# GET /meetings.json
def index
#meetings = Meeting.all
#meeting = Meeting.new
end
end
Update: I also tried this method as suggested below but it didnt work still
# Change this ArticlesController to your project
RSpec.describe MeetingsController, type: :controller do
describe "GET #index" do
# check index
it "returns a success response" do
get :index
raise response.body
expect(response).to have_http_status(:ok)
end
end
end
This is the error raised
Failures:
1) MeetingsController GET #index returns a success response
Failure/Error: raise response.body
RuntimeError:
# ./spec/controllers/meeting_controller_spec.rb:10:in `block (3 levels) in <top (required)>'
If you are trying to get this value for a debugging purpose you should use byebug or pry gems.
If you choose byebug, add it to your gemfile gem 'byebug' on test environment.
run bundle install and after that you are able to use it on your tests
So replace the puts with byebug
describe "GET #index" do
# check index
it "returns a success response" do
get :index
byebug
expect(response).to have_http_status(:ok)
end
end
At the console now you are exactly there. Just type response.body and enter to print it's value.
When you are done, just type c and then enter to release the console e continue your tests.
Also check here for more information about debugging with byebug
In my case I do it like this:
require 'rails_helper'
describe SuppliersController, type: :controller do
describe 'GET /suppliers' do
let!(:access_token) { create :access_token }
let!(:admin_user_token) do
create :user_token, resource_owner: create(:admin_user)
end
context 'when the requester is an admin' do
it 'returns HTTP status 200 (OK)' do
allow(controller).to receive(:doorkeeper_token) { access_token }
#request.env['HTTP_X_USERTOKEN'] = admin_user_token.token
get :index
raise response.body.inspect ## Here is what prints the value in the console.
body = JSON.parse response.body
expect(response).to have_http_status :ok
expect(body['status']).to eq 'OK'
end
end
end
end
To run the test:
rspec spec/controllers/suppliers/suppliers_controller_index_spec.rb
And it gives me the output:
F
Failures:
1) SuppliersController GET /suppliers when the requester is an admin returns HTTP status 200 (OK)
Failure/Error: raise response.body.inspect
RuntimeError:
"{\"status\":\"OK\",\"message\":\"Your request has been processed successfully.\",\"data\":[],\"page\":{\"current_page\":1,\"prev_page\":null,\"next_page\":null,\"per_page\":25,\"total_pages\":0}}"
# ./spec/controllers/suppliers/suppliers_controller_index_spec.rb:17:in `block (4 levels) in <top (required)>'
Finished in 0.47594 seconds (files took 2.82 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/suppliers/suppliers_controller_index_spec.rb:11 # SuppliersController GET /suppliers when the requester is an admin returns HTTP status 200 (OK)
I have to say raise a runtime error to check variable value is not a good practice,maybe you should try gem 'pry' or gem 'byebug' suggested by #DR7.
Another thing you need make sure is did you run rails s and rspec in different environment?This maybe lead to they connect to separate db.

RSpec 2.3 + Devise 1.0.11

I've got a really old Rails 2.3.18, ruby 1.9.3, rspec 1.x application which we are upgrading and it had restful-authentication in it. So I've replaced that with Devise 1.0.11.
I can login to the application, but my tests will not run;
Here is the test in question
require 'spec_helper'
describe CategoriesController do
context "As a logged in user" do
before do
login_user
current_firm = mock_model(Firm, :id => 1)
controller.stub!(:current_firm).and_return(current_firm)
end
describe "#index" do
it "should render index" do
get :index
response.should render_template('index')
end
end
end
end
Here is the error I get;
NoMethodError in 'CategoriesController As a logged in user#index should render index'
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]=
/home/map7/code/pdfcat/spec/spec_helper.rb:18:in `login_user'
spec/controllers/categories_controller_spec.rb:6:in `block (3 levels) in <top (required)>'
The error happens on this line;
[20, 29] in /usr/local/rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/warden-0.10.7/lib/warden/session_serializer.rb
20 key
21 end
22
23 def store(user, scope)
24 return unless user
=> 25 session[key_for(scope)] = serialize(user)
26 end
The problem is 'session' is nil when I'm at this point.
I've pushed the full code to here: https://github.com/map7/pdfcat/tree/devise
My plan was to get devise working in the tests then I could jump to Rails 3.0 and continue the upgrade.
There's an old message in google groups that I think is relevant: https://groups.google.com/forum/#!topic/rspec/4AHuPtHFD34
It recommends using this:
before do
request.env['warden'].stub(:authenticate!) { double(User) }
end
I'd probably put it in rails_helper.rb so that it runs for all tests

Rspec controller testing - unexpected errors/not sure how to handle it

I use this tests for FacultiesController:
describe FacultiesController do
describe "GET show" do
it "responds successfully with an HTTP 200 status code" do
get :show
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
describe "GET index" do
it "responds successfully with an HTTP 200 status code" do
get :index
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
end
Output:
Failures:
1) FacultiesController GET show responds successfully with an HTTP 200 status code
Failure/Error: get :show
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"faculties"}
# ./spec/controllers/faculties_controller_spec.rb:5:in `block (3 levels) in <top (required)>'
2) FacultiesController GET index responds successfully with an HTTP 200 status code
Failure/Error: #faculties=Faculty.where(:university_id => #university.id).all
NoMethodError:
undefined method `id' for nil:NilClass
# ./app/controllers/faculties_controller.rb:5:in `index'
# ./spec/controllers/faculties_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
1) When I run rake routes I see
faculty GET /faculties/:shortcut(.:format) faculties#show
So, I suppose I need to specify shortcut with this GET. But how?
I tried add :shortcut=>"test", but this didn't work, also tried params: {:shortcut=>"test"}. Nothing works until I just write "GET faculties/test" and also remove line get :show.
Is that as it should to be?
2)
Failure/Error: #faculties=Faculty.where(:university_id => #university.id).all
NoMethodError:
undefined method `id' for nil:NilClass
First of all, it, again, work just fine in browser testing. I use module which helps controller to define #university by subdomain.
How can I pass this to test? Should I just provide some option to get index? By the way, it is all defined in my factories.rb file, as subdomain string is stored in db.
I though may be I should invoke factories new instance in this spec before describe?
university = create(:university)
faculty = create(:faculty)
Thanks in advance.
1) You should create a new faculty and pass it's id
describe "GET show" do
let(:faculty) {FactoryGirl.create(:faculty)}
it "responds successfully with an HTTP 200 status code" do
get :show, :id => faculty.id #or get :show, :shortcut => faculty.id
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
2) You should create faculty & university & pass it as params
describe "GET index" do
let(:university) {FactoryGirl.create(:university)}
before(:each) do
FactoryGirl.create(:faculty, :university_id => university.id)
end
it "responds successfully with an HTTP 200 status code" do
get :index, university_id => university.id
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
Please provide index route if it wouldn't work

Shoulda Test in Rails 3: should respond_with :success

I have some troubles with testing in Rails 3. I'm currently upgrading a Rails2 app to Rails3. I'm using shoulda for testing. In my functional tests, I'm testing with shoulda, that a GET should respond with success
context "GET to :blame" do
should "mark a song as blamed" do
get :blame, :id => #song.id
assert_equal Blame.count, 1
get :blame, :id => #song.id
assert_equal Blame.count, 2
end
should respond_with :success
end
In the next to last line I'm getting the following error while executing the functional tests with rake test:functionals:
1) Error:
test: a visitor GET to :blame should respond with 200. (SongsControllerTest):
NoMethodError: undefined method `response_code' for nil:NilClass
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/activesupport-3.0.3/lib/active_support/whiny_nil.rb:48:in `method_missing'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/action_controller/matchers/respond_with_matcher.rb:57:in `response_code'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/action_controller/matchers/respond_with_matcher.rb:48:in `correct_status_code?'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/action_controller/matchers/respond_with_matcher.rb:30:in `matches?'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/assertions.rb:53:in `assert_accepts'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/context.rb:324:in `block in should'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/context.rb:382:in `call'
/Users/23tux/.rvm/gems/ruby-1.9.2-p136#rails3/gems/shoulda-2.11.3/lib/shoulda/context.rb:382:in `block in create_test_from_should_hash'
I'm using Ruby 1.9.2, Rails 3.0.3 and Shoulda 2.11.3.
Hope, someone can help me.
thx,
tux
The two should blocks are run separately and no request would be made for respond_with hence the error. You would need to make the request in a setup block such as:
context "GET to :blame" do
setup do
get :blame, :id => #song.id
end
should "mark a song as blamed" do
assert_equal Blame.count, 1
end
should respond_with :success
end

Resources