Try to add rspec tests to my App and have following error:
NoMethodError:
undefined method `cookies' for #
Here is my simple code:
get :my_action, params: { id: #request.id }
expect(response.status).to eq(200)
But I do not use anywhere cookies in my App project. And why 'coockies' try to executes for my Request model object?
What could it be?
PS Request - it is my model (has :title, :description)
Found error... I have own model Request, and I use instance variable in RSpec test like:
#request = Request.create(....
But RSpec already uses this instant variable:
request
=> #<ActionController::TestRequest:0x007fa8d3b54fb8
#controller_class=RequestsController,
#custom_param_parsers=
The issue was related with rewriting necessary RSpec #request with my data
Related
I have a controller spec for my application, which tests the create method on a controller. The create action actually works fine, but the spec is failing. It seems that it is auto converting the the hash POST param into a string.
let(:coupon) { attributes_for(:coupon) }
describe 'POST #create' do
it 'should create a new coupon from params' do
expect {
post :create, :coupon => coupon
}.to change(Coupon, :count).by(1)
end
end
Now, If I do puts coupon it is generating a valid hash of data, and the type is hash. For some reason the controller is receiving a string for params[:coupon]. Only in rspec testing does this happen, when I test in the browse with a POST form it works perfectly fine.
Rspec throws the following message:
NoMethodError:
undefined method `permit' for #<String:0x00000005062700>
Did you mean? print
and if I do puts params[:coupon].class in the controller in rspec it gives me String. Why might it be converting my hash into a string for the POST request, and how can I prevent this ?
I am using Rails 5.0.0 and rspec 3.5.1
This exact same behavior showed up for me recently when testing a JSON API endpoint. Originally I had this as my subject:
subject { put :my_endpoint, **input_args }
and an integer value in input_args was getting translated into a string. The fix was to add format: 'json' as an additional keyword argument to put:
subject { put :my_endpoint, **input_args, format: 'json' }
It seems that it was an issue with the gem open_taobao somehow transforming my post requests in tests.
I am currently trying to write unit tests for user authentication in rails and I keep running into a problem.
I am trying to test the following method:
def reset_session_token!
self.session_token = User.generate_session_token
self.save!
self.session_token
end
with the following unit test:
let(:valid_user) { User.new(user_name: 'Name', password: 'abcdefghijkl')}
it "should set the session_token" do
valid_user.reset_session_token!
expect(valid_user.session_token).not_to be_nil
end
but the test fails with the error Validation failed: User name has already been taken. I suspect that it is because reset_session_token! calls save on the user instance but this is necessary for the method to work properly. How can I get around this?
Thanks to Oleg Sobchuk's comment I was able to figure out how to deal with the save! method.
Since stub has been deprecated I used allow_any_instance_of with receive instead. Here is what I did:
it "should set the session_token" do
allow_any_instance_of(User).to receive(:save!).and_return(nil)
valid_user.reset_session_token!
expect(valid_user.session_token).not_to be_nil
end
I have an application running in rails 4.1 using mongoid as the orm. I created a model called User which has an attribute email. I am using RSpec for tests. I created the following spec
require 'spec_helper'
describe 'User' do
before(:each) do
#attr = {
user: {
email: "rahul#gmail.com"
}
}
end
it "should create a valid User instance" do
param = ActionController::Parameters.new(#attr)
param.require(:user).permit!
User.create!(param)
end
end
when I run the spec, I get the following error
Failure/Error: User.create!(param)
ActiveModel::ForbiddenAttributesError:
ActiveModel::ForbiddenAttributesError
I know this is related to strong parameters but couldn't figure out what I am doing wrong.
From the fine manual:
require(key)
[...] returns the parameter at the given key [...]
So saying param.require(:user) does nothing at all to param, it merely does an existence check and returns param[:user].
I think you want to say something more like this:
param = ActionController::Parameters.new(#attr)
User.create!(param.require(:user).permit!)
That usage would match the usual:
def some_controller_method
#user = User.create(user_param)
end
def user_param
param.require(:user).permit!
end
usage in controllers.
I want to test a rails engine by using capybara and factory_girl with Test::Unit (not rspec).
I write the following test:
test 'get review show' do
review = create(:review)
visit aecs_review.admin_review_path(review.id)
assert true
end
rake test now get the following error:
1) Error:
NavigationTest#test_get_review_show:
ActionView::Template::Error: undefined method `reviewnumber' for nil:NilClass
D:/Webserver/rails-server/ecommerce/aecs_review/app/views/aecs_review/admin/reviews/show.html.erb:1:in `_____ebserve
r_rails_server_ecommerce_aecs_review_app_views_aecs_review_admin_reviews_show_html_erb___218004451_53574504'
reviewnumber is a small model method to give back a formated id. It is executed by #review.reviewnumber in the view.
I get also errors at the other views (index, ect.) at the points, where i try to access a attribute of a variable.
Why are the variables in the views always nil?
How can I solve this problem?
Here is my controller method:
require_dependency 'aecs_review/application_controller'
module AecsReview
class Admin::ReviewsController < ApplicationController
def show
#review = Review.find(params[:id])
end
end
end
And my view:
<h1>Rezension anzeigen: <%= #review.reviewnumber %></h1>
[...]
rake routes of the dummy app of the engine:
root GET / aecs_review/admin/reviews#index
admin_reviews GET /admin/index(.:format) aecs_review/admin/reviews#index
admin_review GET /admin/:id/show(.:format) aecs_review/admin/reviews#show
admin_review_toggle_visibility GET /admin/:id/toggle_visibility(.:format) aecs_review/admin/reviews#toggle_visibility
admin_review_destroy GET /admin/:id/destroy(.:format) aecs_review/admin/reviews#destroy
review_create POST /create(.:format) aecs_review/reviews#create
reviews GET /product/:id(.:format) aecs_review/reviews#index
reviews_overview GET /product/:id/overview(.:format) aecs_review/reviews#overview
reviews_rating GET /product/:id/rating(.:format) aecs_review/reviews#rating
review_new GET /product/:id/new(.:format) aecs_review/reviews#new
review GET /:id(.:format) aecs_review/reviews#show
review_edit GET /:id/edit(.:format) aecs_review/reviews#edit
review_update PATCH /:id/update(.:format) aecs_review/reviews#update
review_destroy GET /:id/destroy(.:format) aecs_review/reviews#destroy
review_create_evaluation_good GET /:id/create_evaluation/good(.:format) aecs_review/reviews#create_evaluation_good
review_create_evaluation_bad GET /:id/create_evaluation/bad(.:format) aecs_review/reviews#create_evaluation_bad
review_create_evaluation_abusing GET /:id/create_evaluation/abusing(.:format) aecs_review/reviews#create_evaluation_abusing
I found the problem!
In the controller I have a before_filter, which is a part of the main app. So I wanted to override it. But i accidentally override the complete controller, so there was no more controller method to execute.
Now I skip the before_filter and it works!
The following generates an error: "undefined local variable or method `params'"
assert_equal params[:recipient_id], users(:one).id
How do you test the params hash?
Also, how do you test assert_redirect when there are params present? The params are appended to the URL, so testing for model_path or similar fails.
Working with built in test class in Rails 3.
http://guides.rubyonrails.org/testing.html#functional-tests-for-your-controllers gives some of this information.
In this case, params is attached to the #request or #response object (depending on what HTTP method you are testing), so you can refer to it as #request.params[:recipient_id].
For redirect:
assert_redirected_to post_path(assigns(:post)) will assert that you are redirected to the proper path for a given model. The assigns method should have the instance variables you are setting inside of the controller to pass to the view