This is my code:
before(:each) do
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials(api_key.access_token)
end
My test was supposed to pass but it is displaying this error:
Failure/Error: request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials("#{api_key.access_token}")
ArgumentError:
wrong number of arguments (0 for 1..2)
Gems:
rspec-rails version = 2.14.1.
rails verison = 4
mongoid from 'git://github.com/mongoid/mongoid.git'
The request method you are accessing in your test is documented at http://rubydoc.info/gems/rack-test/0.6.2/Rack/Test/Session:request and expects 1 or 2 arguments as the error indicates. You're getting an error on request.env because you're invoking request with no arguments.
Related
Getting below error message when running Rspec after upgrading Ruby to 3.0.3
Failure/Error: FactoryBot.lint strategy: :build_stubbed
FactoryBot::InvalidFactoryError:
The following factories are invalid:
user - wrong number of arguments (given 1, expected 0; required keywords: event_type, object, summary, author) (ArgumentError)
I am trying to set a session variable in a request spec.
I have tried the following things to do this:
RSpec.describe 'Application Controller' do
context 'updating an application' do
before :each do
#app = create(:application, step: 'investigation')
end
it 'should update app status' do
Status.create(app_id: #app.id, name: Status.names[:start])
request.session[:app_id] = #app.id
patch "/applications/start",
params: s_params
expect(response).to redirect_to(offers_path)
end
end
end
I have tried substituting request with #request both result in the same output.
NoMethodError:
undefined method `session' for nil:NilClass
then I have tried just setting as:
session[:app_id] = #app.id
which will yield:
NoMethodError:
undefined method `session' for nil:NilClass
and also setting it like this:
patch "/applications/start",
params: s_params,
session: {"app_id" => #app.id}
which will yield:
ArgumentError:
unknown keyword: session
My versions:
╰>>> ruby -v
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]
╰>>> rails -v
Rails 5.2.1
╰>>> rspec -v
RSpec 3.8
- rspec-core 3.8.0
- rspec-expectations 3.8.1
- rspec-mocks 3.8.0
- rspec-rails 3.8.0
- rspec-support 3.8.0
Looking at the documentation it suggests we could leverage the sessions but does not give a clear example of how we would do this.
First of all, little remark...
I recommend using 'type:' for RSpec test definition. It's good in anyways: easy to determinate by review and we will have the ability to define some extensions/customization for that type of tests(if needed).
The second point
We don't have request / response / controller methods(instance) before the request. Only after request, we will have them. By this reason we can't use request.session[:app_id] = #app.id before patch in your example...
The third point
#app it is a risky name of variable, not sure it will be a problem or not, but will be better to rename it
One of the possible solution
You can try to use some stubs for it, for example:
allow_any_instance_of(ActionDispatch::Request).to receive(:session) { { app_id: '11' } }
Notes
The requests methods get / post / patch / and etc are differrent from similar controller test methods. All they are handling by process method. More details you can find here
The most straightforward approach that comes into my mind is to mock the controller before doing the request:
session = { app_id: #app.id }
allow_any_instance_of(SomeController).to receive(:session).and_return(session)
get some_resources_path
expect(response).to ...
I have some problems while testing my Rails aplication.
I have the simple following file to test a controller (relying on http://guides.rubyonrails.org/testing.html):
require "./test/test_helper"
class GraphControllerTest < ActionDispatch::IntegrationTest
setup do
#instance = Instance.where(client_id: 2).first
end
test "should_create" do
assert_difference('Graph.count') do
post v2_instance_graphs_url(instance_id: #instance.client_id), {'name': "test of test", 'instance_id': #instance.client_id}.to_json, {'Authorization': 'Token token=blabla', 'Content-Type': 'application/json'}
end
assert_equal JSON.parse(#response.body)["name"], "test of test"
end
end
With a test_helper.rb which is:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
fixtures :all
# Add more helper methods to be used by all tests here...
end
I run in console:
bin/rake test test/controllers/knowledge_graph_controller_test.rb
which should trigger only the two assertions above. However, and I get the two assertions above AND 8 errors.
the errors are the following:
1) Error:
ActiveSupport::TestCase#test_app=:
ArgumentError: wrong number of arguments (given 0, expected 1)
2) Error:
ActionController::TestCase#test_app=:
ArgumentError: wrong number of arguments (given 0, expected 1)
3) Error:
Minitest::Test#test_app=:
ArgumentError: wrong number of arguments (given 0, expected 1)
4) Error:
GraphControllerTest#test_app=:
ArgumentError: wrong number of arguments (given 0, expected 1)
5) Error:
ActionDispatch::IntegrationTest#test_app=:
ArgumentError: wrong number of arguments (given 0, expected 1)
6) Error:
Minitest::Unit::TestCase#test_app=:
ArgumentError: wrong number of arguments (given 0, expected 1)
7) Error:
Rails::Generators::TestCase#test_app:
RuntimeError: You need to configure your Rails::Generators::TestCase destination root.
8) Error:
Rails::Generators::TestCase#test_app=:
RuntimeError: You need to configure your Rails::Generators::TestCase destination root.
which I cannot explain. I don't even understand what file they come from.
I am using Rails 4.2.7.1
Thank you very much for your help!
The problem was an "include ActionDispatch" in another file.
I am using Rails 4.2.6, Ruby 2.2.1, rspec-rails 3.4.2, Grape 0.16.2, grape_token_auth 0.1.0. I installed apartment gem (1.0.2) for multitenancy and trying to write rspec tests for grape requests.
But I am getting the following error from rspec-rails response method every time irrespective of whatever solutions I tried.
#buf=["<!DOCTYPE html>\n<html>\n<head>\n <title>Apartment::TenantNotFound at /content/api/v1/questions</title>\n</head>\n<body>\n
The request is taking the host as 'www.example.com' all time. I tried so many solutions by googling it. But nothing works. you can see that in spec where I commented these lines. I want the url as 'http://g_m.lvh.me:3000' with the subdomain 'g_m'.
I tried this one:
https://github.com/influitive/apartment/wiki/Testing-Your-Application
But not works. I don't know why.
I tried this, but not working:
Rails: Wrong hostname for url helpers in rspec
and tried to set the host by:
host! "g_m.lvh.me:3000"
#request.host = 'g_m.lvh.me:3000'
request.host = 'g_m.lvh.me:3000'
Nothing works!
I created a test case like the following grape link says:
https://github.com/dblock/grape/commit/99bf4b44c511541c0e10f4506bf34ae9abcccd75
require 'rails_helper'
RSpec.describe ContentManager::QuestionAPI, :type => :request do
#before(:each) { Apartment::Tenant.switch!("g_m") }
#after(:each) { Apartment::Tenant.switch!("public") }
#before(:each) do
#begin
#client = FactoryGirl.create(:client, title: 'Sample title', subdomain: 'g_m')
#rescue
#client = Client.create!(title: 'Sample title', subdomain: 'g_m')
#end
#default_url_options[:host] = 'http://g_m.lvh.me:3000'
# request.host = "#{'g_m'}.lvh.me"
#end
#end
#before(:each) do
# if respond_to?(:default_url_options)
# default_url_options[:host] = 'http://g_m.lvh.me:3000'
# end
#end
describe "GET /content/api/v1/questions" do
it "returns an empty array of questions" do
get "/content/api/v1/questions"
#puts "response.inspect: #{response.inspect}"
response.status.should == 200
JSON.parse(response.body).should == []
end
end
end
My configurations:
in spec/rails_helper.rb
config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/requests/
All time this request sent by rspec-rails with
url: '/content/api/v1/questions'
host: 'www.example.com'
My test result shows:
$ rspec spec/requests/
F
Failures:
1) ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
Failure/Error: response.status.should == 200
expected: 200
got: 500 (using ==)
# ./spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'
Deprecation Warnings:
Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /home/vagrant/gauge-slcsl/spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 6.19 seconds (files took 1.93 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/requests/question_spec.rb:26 # ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
abhi#ubuntu-trusty-64:~/my-app$
If anyone knows about the error and what I am doing wrong here, please reply/answer.
The error was because of, we have to say the apartment subdomain configuration that just exclude the 'www' word considering as a sub domain.
Add the following:
# config/initializers/apartment/subdomain_exclusions.rb
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
I was using the better_errors gem in my development and test environment. This causes the rspec output as an better error generated html codes and difficult to understand the rspec failure reason.
I removed better errors from 'test' environment and I got the clue of this error where we have to exclude the 'www' considering as a subdomain.
Since I updated my Gemfile and moved to rspec 3, in many tests, I'm getting a error for: way:
it "should reject attribute that are too short" do
short = "a" * 3
hash = #attr.merge(:details => short)
Deal.new(hash).should have(1).error_on(:details)
end
I'm getting this error:
Failure/Error: Deal.new(hash).should have(1).error_on(:details)
NoMethodError:
undefined method `have' for #<RSpec::ExampleGroups::Deal_2::TestsOnDealsModelsValidations>
I read I should now be using "expect" instead of should but here with have(1).error_on, how should I write it to comply with rspec 3?
I tried the following but it still does not work:
it "should reject attribute that are too short" do
short = "a" * 3
hash = #attr.merge(:details => short)
expect(Deal.new(hash).error_on(:details).size).to eq(1)
end
I have replaced the likes of
Deal.new(hash).should have(1).error_on(:details)
with
deal = Deal.new(hash)
expect(deal.valid?).to be_falsey
expect(deal.errors[:details].size).to eq(1)
The first expectation with valid? is necessary as it initializes the errors list.
have and other similar matchers have been moved out of rspec core and into another gem, rspec-collection-matchers.
I recommend following the upgrade path from rspec 2 -> 3 as detailed in the rspec docs: https://relishapp.com/rspec/docs/upgrade
Upgrade to rspec 2.99
Run your test suite
Fix deprecation warnings
Upgrade to rspec 3.
If you had done this you would have received a deprecation error with your code that would have also told you what to do to fix it.
The line to add to your Gemfile should be:
gem 'rspec-collection_matchers'