Session is always empty using RSpec - ruby-on-rails

There is the following code:
describe 'Some title' do
before do
session = ActionController::TestSession.new
session[:state] = "12334"
get '/api/v1/menus', format: :json
end
it 'some text' do
expect(response).to be_success
json = JSON.parse(response.body)
puts json
end
end
Code of the controller:
class Api::V1::MenusController < Api::V1::ApiV1Controller
def index
render json: session
end
end
But controller returns an empty session always. How can I fix it?

Try adding this:
describe 'Some title', :type => :controller do
And remove session = ActionController::TestSession.new.
RSpec needs to know you are doing "controller things" in your test. You indicate this as above or by placing the test in spec/controllers.

Related

Error occuring in testing my controller with RSPEC using shoulda matchers especially create i can't able to test save functionality

I am testing my controller with RSPEC using shoulda matchers while i came across the create method in my controller i cant test the save function if i try to do that i go the error
Expected response to be a <3XX: redirect>, but was a <200: OK>
i have attached my controller part and testing and route
In testing
RSpec.describe "routes for home", type: :routing do
describe 'post #create' do
before do
post :create , params: params
end
context 'when the params are correct' do
let(:params) { { restaurant: { restaurantname: "Buhari" ,location_id: 1} } }
it 'is expected save successfully and redirect_to gridpage' do
expect(assigns[:restaurant].save).to redirect_to(gridurl_path)
end
end
end
end
In controller
def create
# render plain: params
#restaurant=Restaurant.new(restaurant_params)
if #restaurant.save
redirect_to gridurl_path
else
render 'index'
end
end
In routes
post "/home/create", to: "home#create", as: :createurl
get '/home/grid', to: 'home#grid',as: :gridurl
Thank you in advance
First I suggest you read https://relishapp.com/rspec/rspec-rails/docs/controller-specs and also the other docs. They will give you a good starting point on how to test stuff with rspec.
When you look at a controller action, you are not interested on who's doing what (i.e assigns[:restaurant]) - you want to see if a redirect happens, if something is saved in the DB, etc. Think of it from the perspective of a user calling that endpoint. Does the user know all of the internals?
Here is how it should look like:
describe "routes for home", type: :controller do
describe 'post #create' do
context 'when the params are correct' do
let(:params) { { restaurant: { restaurantname: "Buhari" ,location_id: 1} } }
it 'is expected save successfully and redirect_to gridpage' do
post :create, params: params
expect(response).to redirect_to('/home/grid')
end
end
end
end

Rspec Test Controller download excel Rails

Hi I tried to add test to my controller I have a method that download a excel file
In my method controller i have this code.
def download_syllabus_evaluation_system
#syllabus_programs = SyllabusProgram.match_course_coordinator.actives.order(:id)
name_file = "Syllabus_evalution_system"
setHeaderExportExcel(name_file)
respond_to do |format|
format.excel { render template: '/syllabuses/excel/syllabus_evaluation_system', layout: 'report/excel/template', status: :ok}
end
end
And this method that set Header
def setHeaderExportExcel(name_file)
headers['Content-Type'] = "application/vnd.ms-excel; charset=UTF-8; charset=ISO-8859-1; header=present"
headers['Content-Disposition'] = 'attachment; filename="' + name_file +'.xls"'
headers['Cache-Control'] = ''
end
In My Rspec Controller I have this code
require 'rails_helper'
#TODO: add test controller
RSpec.describe SyllabusesController, type: :controller do
describe "syllabus_program#update " do
context "as an authorized " do
before do
##user = FactoryBot.create(:user)
end
end
end
describe "GET#download_syllabus_excel" do
it "return succes response" do
get download_syllabus_evaluation_system_path(format: "excel")
expect(response).to be_successful
end
end
end
And my route is
get 'download_syllabus_evaluation_system' => 'syllabuses#download_syllabus_evaluation_system', as: "download_syllabus_evaluation_system"
But when i run the test , i get this error
Failure/Error: get download_syllabus_evaluation_system_path(format: "excel")
ActionController::UrlGenerationError:
No route matches {:action=>"/download_syllabus_evaluation_system.excel", :controller=>"syllabuses"}
Whats the problem?

Expected response to be a <redirect>, but was <200>

Hi guys i have a controller code with the following :
class FeedbacksController < ApplicationController
def create
#feedback = Feedback.create(feedback_params)
if #feedback.errors.any?
flash[:error] = #feedback.errors
render 'new'
else
redirect_to :back
end
end
test spec
require "rails_helper"
RSpec.describe FeedbacksController do
describe "POST create" do
context 'when param[:name] is present' do
it 'should redirect to homepage' do
#feedback = Feedback.create(:name => "Hah")
#feedback.save
is_expected.to redirect_to new_feedback_path
debugger
end
end
end
end
However when i run localhost, the output is exactly what i want but as of the unit test, it's not passing but returning me
"Expected response to be a m was was <200> ."
May i know why is it so and how should i pass my test case ?
You are missing the actual post request to your controller.
Please read this: rspec documentation
So this:
#feedback = Feedback.create(:name => "Hah")
#feedback.save
Should not be there. The second line is superfluous anyway, create already saves the object.
You are looking for code like this:
it 'should redirect to homepage' do
post feedback_path, params: { name: 'hah' }
expect(response).to redirect_to(new_feedback_path)
end

How to install session for RSpec in Rails?

There is the following spec:
describe 'Some title' do
before do
session[:state] = "12334"
get '/api/v1/menus', format: :json
end
it 'some text' do
expect(response).to be_success
json = JSON.parse(response.body)
puts json
end
end
It code tests the following controller's action:
class Api::V1::MenusController < ActionController
def index
render json: session
end
end
But I've got the following exception: "undefined method `session' for nil:NilClass". How can I fix it? How can I make a new example of a session? Thanks in advance.
Try this:
describe 'Some title', :type => :controller do
RSpec needs to know you are doing "controller things" in your test. You indicate this as above or by placing the test in spec/controllers.

Testing mocked model with RSpec2 returning 0 items and no response body

I am attempting to create an API with Rails using BDD with RSpec.
Rails version is 3.1.1, Ruby version is 1.9.2, Devise version is 1.5.3, and rspec version is 2.7.0. I am relatively new to Rails and very new to RSpec.
I have defined a simple RSpec as follows to test a FormsController with essentially no logic.
describe FormsController, " handling GET /forms" do
include Devise::TestHelpers
render_views
before do
user = Factory.create(:user) # Handle Devise authentication
user.confirm!
sign_in user
#form = mock_model(Form)
Form.stub!(:all).and_return([ #form ])
end
it "gets successfully" do
get :index, :format => :json
response.should be_success
end
it "finds all forms" do
Form.should_receive(:all).and_return([#form])
get :index, :format => :json
Rails.logger.info "*** response.body="+response.body
end
end
Form controller code is very simple currently.
class FormsController < ApplicationController
before_filter :authenticate_user!
# GET /forms
# GET /forms.json
def index
#forms = Form.find_all_by_owner_id(current_user.id)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #forms }
end
end
end
When I run the spec, "finds all forms" always fails with
Failure/Error: Form.should_receive(:all).and_return([#form])
(<Form(id: integer, title: string, owner_id: integer, created_at: datetime, updated_at: datetime) (class)>).all(any args)
expected: 1 time
received: 0 times
The output from log/test.log shows:
*** response.body=[]
Why? I feel that the problem stems from Form.stub!(:all).and_return([ #form ]), but I am not sure how to debug.
Thanks in advance.
It would help to post your controller code (that is being tested). The error says that the declaration Form.should_receive(:all).and_return([#form]) has not been satisfied. The declaration says you should have code like this in your controller's action: Form.all.
find_all_by_owner_id is not the same as Form.all. find_all_by_owner_id ends up doing
Form.where(...).all
which doesn't match the expectations you've set. In your particular case I'd tell should_receive that I'm expecting a call to find_all_by_owner_id rather than all.
After much more trial and error, the following solution worked for me.
I migrated from mocking the Form model to using Factory Girl to create the full model
I then updated the test to use to_json to compare the response against the model.
The spec is as follows.
describe FormsController, " handling GET /forms" do
include Devise::TestHelpers
render_views
before do
user = Factory.create(:user) # Handle Devise authentication
user.confirm!
sign_in user
#form1 = Factory.create(:form)
end
it "gets successfully" do
get :index, :format => :json
response.should be_success
end
it "finds all forms" do
get :index, :format => :json
response.body.should == [ #form1 ].to_json
Rails.logger.info "*** response.body="+response.body
end
end

Resources