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?
Related
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
I have a following method in my controller:
def create
#job = Job.new(job_params)
if #job.save
render 'create_success', status: :created
else
render 'create_failure', status: :bad_request
end
end
And here are my controller specs for this:
require 'rails_helper'
RSpec.describe Api::V1::JobsController, :type => :controller do
let(:actor) { FactoryGirl.create(:user, :service_advisor) }
let(:auth_token) { actor.authentication_token }
describe 'POST #create' do
render_views
context 'with invalid attrubutes' do
let(:job) { FactoryGirl.build(:job, customer_id: nil).attributes }
it 'renders create_failure view' do
expect(response).to render_template :create_failure
end
it 'returns 400 status code' do
expect(response.status).to eq 400
end
end
end
end
However, for some reason, no matter what i do, the controller spec allways thinks that this method returns empty response and status 200. I can test that method using postman or curl and it works as expected - return error messages and status codes (201/400) but my spec allways sees it as empty response with 200 status code.
It seems that render_views is not working. My env is:
ruby 2.0.0p594
Rails 4.1.0
rspec 3.1.5
You have not given call to create action in your test case.
it 'renders create_failure view' do
post :create, job
expect(response).to render_template :create_failure
end
I want to test the controller method, but I can not find the example of testing method with order and search .
This is my controller:
class Admin::HotelsController < Admin::BaseController
helper_method :sort_column, :sort_direction
def index
#hotels = Hotel.search(params[:search], params[:search_column]).order(sort_column + ' ' + sort_direction)
end
def show
#hotel = Hotel.find(params[:id])
end
def update
#hotel = Hotel.find(params[:id])
if #hotel.update_attributes(hotel_params)
redirect_to admin_hotels_path
else
render(:edit)
end
end
private
def hotel_params
params.require(:hotel).permit(:title, :description, :user_id, :avatar, :price, :breakfast, :status, address_attributes: [:state, :country, :city, :street])
end
def sort_column
Hotel.column_names.include?(params[:sort]) ? params[:sort] : 'created_at'
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc'
end
end
This is test for this controller.
require 'rails_helper'
describe Admin::HotelsController do
login_admin
describe 'GET index' do
it 'render a list of hotels' do
hotel1, hotel2 = create(:hotel), create(:hotel)
get :index
expect(assigns(:hotels)).to match_array([hotel1, hotel2])
end
end
describe 'GET show' do
it 'should show hotel' do
#hotel = create(:hotel)
get :show, { id: #hotel.to_param, template: 'hotels/show' }
expect(response).to render_template :show
end
end
end
I don't know how testing index method. Please help or give me a link with information about this. Thanks!
If it may help you, I personally prefer to have minimals tests for the controllers for various reasons:
1) as I was beginning in rails testing I read many articles saying it's a good idea
2) it allows you to tests in isolation model methods:
describe 'GET index' do
it 'render a list of hotels' do
hotel1, hotel2 = create(:hotel), create(:hotel)
get :index
expect(assigns(:hotels)).to match_array([hotel1, hotel2])
end
end
here your test matches the result of your query on the model. You can split it like this:
describe 'GET index' do
it 'render a list of hotels' do
hotel1, hotel2 = create(:hotel), create(:hotel)
Hotel.should_receive(:search).with(YOUR PARAMS)
get :index
response.response_code.should == 200
end
end
and then test the result of Hotel.search in a model test.
3) it allows you to test the feature and not some random things that are not really relevant:
describe 'GET show' do
it 'should show hotel' do
#hotel = create(:hotel)
get :show, { id: #hotel.to_param, template: 'hotels/show' }
expect(response).to render_template :show
end
end
here "expect(response).to render_template :show" seems like testing that rails rendering system is properly working. I assume that's not what you want to test, you may prefer (that's what I would do):
describe 'GET show' do
it 'should show hotel' do
#hotel = create(:hotel)
Hotel.should_receive(:find).with(YOUR PARAMS)
get :show, { id: #hotel.to_param, template: 'hotels/show' }
response.response_code.should == 200
end
end
and then test what is supposed to appear on the web page with a feature test using something like capybara gem unless you're rendering some json: in this case match the json values in the controller.
By the way: "#hotel = create(:hotel)" the # is not necessary here as you're in the "it". Moreover you can create such entry like this:
context "" do
before(:each) do
#hotel = create(:hotel) # here the # is necessary for the variable to be
end # accessible in the it
it "" do
end
end
or even like this:
context "" do
let(:hotel) { create(:hotel) } # you can call it in the test by using hotel and it
it "" do # will be insert in you db only when it's in the "it"
end # if you want it to be created in the "it" without
end # calling hotel for nothing, use let!
I would suggest using
describe 'GET index' do
let(:hotel1) { create(:hotel) }
let(:hotel2) { create(:hotel) }
it 'render index template' do
get :index
expect(response).to render_template :index
end
it 'render asc ordered hotels' do
get :index
# if you are using json responses
json = JSON.parse(response.body)
expect(json['hotels'].first).to eq hotel1
expect(json['hotels'].last ).to eq hotel2
# or any similar approach to get test the hotels in response
end
it 'render desc ordered hotels' do
get :index, {direction: 'desc'}
# if you are using json responses
json = JSON.parse(response.body)
expect(json['hotels'].first).to eq hotel2
expect(json['hotels'].last ).to eq hotel1
# or any similar approach to get test the hotels in response
end
# you can complete these tests yourself
it 'render hotels sorted with different_column_than_created_at asc'
it 'render hotels sorted with different_column_than_created_at desc'
end
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.
I want to put the common controller actions, index, show, create etc. in the ApplicationController like this:
class ApplicationController < ActionController::Base
respond_to :json
def index
#implementation
end
def show
#implementation
end
def update
#implementation
end
end
The app will only return JSON.
I have written the following spec to test this with RSPEC's annonymous controller
describe ApplicationController do
controller do ; end
describe 'Get :index' do
it 'should respond to index' do
get :index
response.code.should eq "200"
end
end
end
The above spec gives the following error:
ActionView::MissingTemplate: Missing template anonymous/index,
application/index with {:locale=>[:en], :formats=>[:json],
:handlers=>[:erb, :builder]}. Searched in: *
"#"
Can anyone suggest a way to make this work with the anonymous controller?
try this may be it helpful
your controller like
def index
end
your rspec testing like
describe "GET index" do
it "should respond to index" do
get :index
response.code.should eq "200"
end
end
create index.html.erb in your application/ folder
then test it.
describe "GET index" do
it "returns correct JSON" do
# #groups.should have(2).items
get :index, :format => :json
response.should be_success
body = JSON.parse(response.body)
body.should include('group')
groups = body['group']
groups.should have(2).items
groups.all? {|group| group.key?('customers_count')}.should be_true
groups.any? {|group| group.key?('customer_ids')}.should be_false
end
end