I have a function that sends a variable to js with the help of gon.
def calc_foo
# calculate foo
gon.foo = foo
end
I want to test this function ie make sure that the method return the correct value, using rspec.
it "should return bar" do
foo = @foo_controller.calc_foo
expect(foo).to eq(bar)
end
But, I get the following error message when the test case reaches the line where the variable is sent to gon.
Failure/Error: foo = @foo_controller.calc_foo
NoMethodError:
undefined method `uuid' for nil:NilClass
I have checked the value for foo, and it is not Nil, so gon must be Nil. I believe the error is that I don't incude gon correctly. This is the rspec-part of my Gemfile
#rspec-rails includes RSpec itself in a wrapper to make it play nicely with Rails.
#Factory_girl replaces Rails’ default fixtures for feeding test data
#to the test suite with much more preferable factories.
group :development, :test do
gem 'rspec-rails'
gem 'factory_girl_rails'
gem 'capybara'
gem 'gon'
end
So how can I get rspec to play nicely with gon? (I have also tried to include gon in my spec-file with no success)
I test that the controller passes the right stuff to gon in a request spec.
The controller sets an array of objects -- eg , gon.map_markers = [...]
My request spec extracts the JSON via regexp (the .split()
and match_array
handle the order-independent-array-ness):
....
# match something like
# gon.map_markers=[{"lat":a,"lng":b},{"lat":c,"lng":d},...];
# and reduce/convert it to
# ['"lat":a,"lng":b',
# '"lat":c,"lng":d',
# ...
# ]
actual_map_markers = response.body
.match('gon.map_markers=\[\{([^\]]*)\}\]')[1]
.split('},{')
expect(actual_map_markers).to match_array expected_map_markers
In the controller specs (where gon
belongs) you'll need to make an actual request to bypass your problem:
RSpec.describe ThingiesController do
let(:gon) { RequestStore.store[:gon].gon }
describe 'GET #new' do
it 'gonifies as expected' do
get :new, {}, valid_session # <= this one
expect(gon['key']).to eq :value
end
end
end
If you'd rather not stick with certain controller
or action
for the gon
-related specs (let's say you have a gon
-related method in your ApplicationController
), you could use Anonymous controller approach:
RSpec.describe ApplicationController do
let(:gon) { RequestStore.store[:gon].gon }
controller do
# # Feel free to specify any of the required callbacks,
# # like
# skip_authorization_check
# # (if you use `CanCan`)
# # or
# before_action :required_callback_name
def index
render text: :whatever
end
end
describe '#gon_related_method' do
it 'gonifies as expected' do
get :index
expect(gon['key']).to eq :value
end
end
end
I have lots of controller
and request
/ integration
specs and can confirm that gon
behaves fine there as long as you make actual requests.
However, I still have a problem similar to yours although the case is different (making requests from the shared_examples
included in the controller
specs). I've opened the relevant issue , feel free to join the conversation (for anyone interested).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.