Testing Views in Rspec , undefined method collect - ruby-on-rails

I got this following error while i am testing views in Rspec.
1) problems/new renders new problem form
Failure/Error:
<div class="col-md-8 col-sm-8">
<%= f.select :approval_status, options_for_select(#approval_statuses.collect { |as| [as[0].humanize, as[0]] }, selected: #problem.approval_status), {}, class: "form-control" %>
</div>
ActionView::Template::Error:
undefined method `collect' for nil:NilClass
I am passing #approval_statuses in controller action.
It's working fine in views , but in test cases i am getting this error.
Controller Action :
def new
#problem = Problem.new
#approval_statuses = Problem.approval_statuses
#visibilities = Problem.visibilities
end
In Model
enum approval_status: {not_approved: 0, approved: 1}
In new.html.erb_spec.rb
require 'rails_helper'
RSpec.describe "problems/new", type: :view do
before(:each) do
assign(:problem, Problem.new())
end
it "renders new problem form" do
render
assert_select "form[action=?][method=?]", problems_path, "post" do
end
end
end

You're setting the #problem instance variable but not #approval_statuses or #visibilities so these are both currently nil.
RSpec.describe "problems/new", type: :view do
before(:each) do
assign(:problem, Problem.new)
assign(:approval_statuses, Problem.approval_statues)
assign(:visibilities, Problem.visibilities)
end
it "renders new problem form" do
render
assert_select "form[action=?][method=?]", problems_path, "post" do
end
end
end

Related

Rails: Get error on RSpec testing View edit form

I have some errors while testing with RSpec. This is my code:
\spec\views\post_categories\edit.html.haml_spec.rb
require 'rails_helper'
RSpec.describe "post_categories/edit", type: :view do
before do
login_user
#post_category = FactoryBot.create(:post_category)
end
it "renders the edit post_category form" do
render
assert_select "form[method=?]", "post" do
assert_select "input[name=?]", "post_category[title]"
assert_select "textarea[name=?]", "post_category[description]"
end
end
end
After it I get such an error:
post_categories/edit renders the edit post_category form
Failure/Error: = simple_form_for(#post_category) do |f|
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"post_categories", :locale=>#<PostCategory id: 1, title:
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", description:
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...", reated_at:
"2021-11-15 11:04:50.292970000 +0000", updated_at: "2021-11-15
11:04:50.292970000 +0000">}, missing required keys: [:id]
Did you mean? post_category_url
admin_post_category_url
The #post_category exsist and corrrect, but simple_form doesn't work on test
Why #post_category got in :locale and how it repair?
I changed all link_to <subject> to link_to <subject>_path(id: subject.id)
Why it needed for rspec I don't know

Rails rspec helper methods not recognised in tests

I have a helper method that hides some buttons depending on user role.
#application_controller
helper_method :current_user, :manager_can_see
def manager_can_see(company)
#if manager can see, company owner can see as well
if current_user
return current_user.has_role?(:manager, company) ||
current_user == company.user ||
current_user.has_role?('superuser')
end
end
Then in my view I have this line:
<% if manager_can_see(#appliance.company) %>
...
<% end %>
This works when I visit that page. But it fails in rspec test saying:
ActionView::Template::Error:
undefined method `manager_can_see'
What can be the reason and solution to this?
Here is my test:
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'admin/show', type: :view do
before(:each) do
#user = assign(:user, FactoryBot.create(:user))
#company = assign(:company, FactoryBot.create(:company, user: #user))
10.times do |i|
FactoryBot.create(:appliance, company: #company, name: "Test object #{i}")
end
session[:user_id] = #user.id
#companies = Company.where(user: current_user)
#appliance = assign(:appliance, FactoryBot.create(:appliance))
end
I18n.available_locales.each do |_locale|
it 'renders attributes in <p>' do
render
end
end
end

Rails rspec undefined method for #<RSpec::ExampleGroups

I have set_seo method in my ApplicationController
def set_seo(page)
set_meta_tags :site => '', :title => page.seo_title ? page.seo_title : '', :reverse => true,
:description => page.seo_description ? page.seo_description : ""
end
and want to test my BrandsController which includes this method
def index
#some code here
set_seo(#content)
end
my controller spec
require 'spec_helper'
describe BrandsController do
render_views
before(:all) do
#content = create(:content)
create(:user)
end
describe "GET index" do
it "index" do
allow(ApplicationController).to receive(set_seo(#content)).and_return(set_seco(#content))
brand = Brand.create
get :index
expect(response).to render_template(:index)
end
but i have got
NoMethodError:
undefined method `set_seo' for #<RSpec::ExampleGroups::BrandsController::GETIndex:0x007f866daa96c8>
set_seo isn't defined in your specs, hence the undefined method error. You have to pass methods as symbols for mocks/stubs (In other words you're replacing or "mocking" the behavior of the method, not calling it directly).
That said, what's the point of this line: allow(ApplicationController).to receive(set_seo(#content)).and_return(set_seco(#content))? Isn't it telling :set_seo to return what it already returns?
If you're trying to ensure that set_seo is actually called, use the following:
expect_any_instance_of(ApplicationController).to receive(:set_seo).with(#content).and_call_original

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"

How to test Devise in a Controller RSpec, error: undefined method `assign' for #<RSpec::Core::ExampleGroup::Nested_1:0x0000010597f4b8>

I'm getting the following error:
undefined method `assign' for #<RSpec::Core::ExampleGroup::Nested_1:0x0000010597f4b8>
When attempting to test per the docs.
Here's is what I have:
user_controller_spec.rb
require 'spec_helper'
describe "devise/sessions/new.html.erb" do
let(:user) do
stub_model(User).as_new_record
end
before do
assign(:user, user)
# Devise provides resource and resource_name helpers and
# mappings so stub them here.
#view.stub(:resource).and_return(user)
#view.stub(:resource_name).and_return('user')
#view.stub(:devise_mapping).and_return(Devise.mappings[:user])
end
it "renders a form to sign the user in" do
render
rendered.should have_selector("form",
:method => "post",
:action => user_session_path
) do |form|
form.should have_selector("input", :type => "submit")
end
end
end
Suggestions? Thanks
Rspec has changed a bit, it's now using assigns.
Doc here.

Resources