RSpec error "undefined method `respond_with'..." - ruby-on-rails

I am following the tutorials http://apionrails.icalialabs.com/book/chapter_three
But when I ran the controller test bundle exec rspec spec/controllers I am getting undefined method error:
Failures:
Api::V1::UsersController GET #show
Failure/Error: it { should respond_with 200 }
NoMethodError:
undefined method `respond_with' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x00000005d6f650>
# ./spec/controllers/api/v1/users_controller_spec.rb:17:in `block (3 levels) in <top (required)>'
Finished in 0.08435 seconds
2 examples, 1 failure
Please help
Edit:
The below is the contents of my spec file
users_controller_spec.rb
require 'spec_helper'
describe Api::V1::UsersController do
before(:each) { request.headers['Accept'] = "application/vnd.marketplace.v1" }
describe "GET #show" do
before(:each) do
#user = FactoryGirl.create :user
get :show, id: #user.id, format: :json
end
it "returns the information about a reporter on a hash" do
user_response = JSON.parse(response.body, symbolize_names: true)
expect(user_response[:email]).to eql #user.email
end
it { should respond_with 200 }
end
end

Here since we are dealing with response codes you can use-
it { expect(response).to have_http_status(200) }
instead of it { should respond_with 200 }
Here no need of shoulda-matchers gem as well.
Ref - https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs

I had the same problem and solved it. It looks like using older version of shoulda-matchers helps. I changed the Gemfile to gem "shoulda-matchers", "~>2.5"

Having this error after upgrade my old rails app to rails 5.0. then add the following configuration into spec_helper.rb and now its working fine.
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end

If you're not finding shoulda methods, I'd make sure you have this in your rails_helper.rb or spec_helper.rb:
config.include(Shoulda::Matchers::ActionController, { type: :model, file_path: /spec\/controllers/})
Or it might be there but commented-out.

This seems to be an error from shoulda-matchers gem, try to update to the latest version.
Also make sure that it comes after RSpec in your gemfile
group :development, :test do
gem 'rspec-rails'
gem 'shoulda-matchers'
end

Related

Ruby on Rails - Rspec test with Devise is failing

I have a Problem with an rspec-request-test in my rails app. The tests, that need a user-login are failing. I have implemented the devise-tests according to this tutorial. Also I found many links, that are using a similar approach. e.g. here
Here is an extract of my gemfile:
gem 'devise', '~> 3.5'
gem 'devise-i18n'
gem 'devise-i18n-views'
gem 'cancancan', '~> 1.10'
gem 'rolify'
gem 'alchemy_cms', '~> 3.2.0'
gem 'rspec-core'
gem 'rspec-rails'
gem 'i18n-tasks', '~> 0.8.7'
gem 'factory_girl_rails'
Here is the rspec-test, that is failing: (spec/requests/campaigns_spec.rb)
require 'rails_helper'
RSpec.describe "Campaigns", type: :request do
describe "GET /campaigns" do
it "responds with 200" do
sign_in_as_a_valid_user_request
get campaigns_path
expect(response).to have_http_status(200)
end
end
end
You should only see this page, when you are logged in. So in the test I want to log in as a User (created with FactoryGirl), than go to the site, and get a 200-response. In the application itself this is working good.
spec/rails_helper.rb (extract)
...
require 'spec_helper'
require 'rspec/rails'
require 'devise'
require 'support/devise_support'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include Devise::TestHelpers, type: :controller
config.include Devise::TestHelpers, type: :view
config.include ValidUserRequestHelper
...
end
spec/support/devise_support.rb
module ValidUserRequestHelper
def sign_in_as_a_valid_user_request
#user ||= FactoryGirl.create :user
post_via_redirect user_session_path, 'user[email]' => #user.email, 'user[password]' => #user.password
end
end
here is the error, that the test is throwing:
1) Campaigns GET /campaigns responds with 200
Failure/Error: sign_in_as_a_valid_user_request
ActionController::RoutingError:
Alchemy::Page not found "/"
# ./spec/support/devise_support.rb:13:in `sign_in_as_a_valid_user_request'
# ./spec/requests/campaigns_spec.rb:6:in `block (3 levels) in <top (required)>'
According to the links that I found, this should work! but it doesn't... Can anyone tell me why? Why is there a routing error? The app itself is working fine.
The routing error occurs, because your host app does not know of the engines routes. That's why you have to use the routing proxy objects of rails engines in views outside the current controller scope. Please read more about rails engines and the characteristics of their routes in the official rails guides
Luckily, Alchemy comes with a handy test helper that solves your problems. Just add this to your spec_helper:
# spec/spec_helper.rb
require 'alchemy/test_support/controller_requests'
...
RSpec.configure do |config|
config.include Alchemy::TestSupport::ControllerRequests
...
end
Know you can use alchemy_get instead of get in your request specs.

Factory still not registered after trying solutions provided

I am trying to write an Rspec test for the first time, my model test worked out fine, but I have problems with my controller test. Which seems weird. For my model test, I'm following the example from: https://gist.github.com/kyletcarlson/6234923
I am given the infamous Factory not registered: error. The log is below:
1) ProductsController POST create when given all good parameters
Failure/Error: post :create, product: attributes_for(valid_product)
ArgumentError:
Factory not registered: #<Product:0x007fc47275a330>
# ./spec/controllers/products_controller_spec.rb:12:in `block (4 levels) in <top (required)>'
I have tried solutions given by others and now my files look like this:
Gemfile
group :test, :development do
gem 'shoulda'
gem 'rspec-rails'
gem 'factory_girl_rails'
gem 'database_cleaner'
end
rails_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'factory_girl_rails'
...
RSpec.configure do |config|
...
config.include FactoryGirl::Syntax::Methods
end
/spec/factories/products.rb
FactoryGirl.define do
factory :product do
sequence(:name) { |n| "test_name_#{n}" }
price "1.50"
description "Test Description"
end
end
/spec/controllers/products_controller_spec.rb
require 'rails_helper'
describe ProductsController do
let(:valid_product) { create(:product) }
let(:invalid_product) { create(:product, name: nil, price: 0, description: test_description) }
describe "POST create" do
context 'when given all good parameters' do
before(:each){
post :create, product: attributes_for(valid_product)
}
it { expect(assigns(:product)).to be_an_instance_of(Product) }
it { expect(response).to have_http_status 200 }
end
end
end
Any help will be appreciated. Thanks.
*Updated to include factories details, that was already implemented before question was posed.
On this line
post :create, product: attributes_for(valid_product)
You are calling attributes_for passing valid_product which is an actual instance of Product, hence the error message.
I suspect you intended to write
post :create, product: attributes_for(:product)
You need to specify factory separately. Create spec/factories/products.rb with content:
FactoryGirl.define do
factory :product do
name 'My awesome product'
price 100
description 'Just a simple awesome product'
# add there attributes you need
end
end

Why is my controller sign in utility no longer working after upgrading to RSpec 2.99?

I recently upgraded the RSpec version of my Rails 4 app. This is my setup:
# /Gemfile:
source 'https://rubygems.org'
group :development, :test do
gem 'rspec-rails', '~> 2.99'
...
end
# /spec/controllers/companies_controller_spec.rb:
require 'spec_helper'
describe CompaniesController, :type => :controller do
before(:all) do
#user = FactoryGirl.create(:user)
sign_in(#user)
end
describe 'GET #new' do
it "renders the :new view" do
get :new
expect(response).to render_template :new
end
end
...
end
# /spec/support/utilities.rb:
def sign_in(user)
cookies[:remember_token] = user.remember_token
end
The problem is that most of my tests are now failing and I've been trying to fix it for hours, but to no avail.
This is the error I get for nearly all tests that require a user sign in:
Failure/Error: sign_in(#user)
NoMethodError:
undefined method `cookie_jar' for nil:NilClass
# ./spec/support/utilities.rb:2:in `sign_in'
The #user object gets created by FactoryGirl, however. I've checked that in the test database and in the logs.
Why is my method for signing in users not working?
It worked like a charm before upgrading to a later version of RSpec.
Thanks for any help.
In a before(:all) you shouldn't be doing stuff that only makes sense in the context of a single example.
In particular your sign_in method fiddles with the cookies, which is implicitly the current request/controller's cookies. This doesn't make sense in a before(:all) since each example is supposed to have a separate request - the exception occurs because there is no current request. Change the before(:all) to a before(:each) and you should be ok.
Rspec used to be more lenient in this respect, but 2.99 tightened this up, deprecation warnings were also added for similar uses in some of the earlier 2.x versions (if you had depreciations about using let/subject in a before(:all) block, that was it)

Rspec failure when it should be passing

When I run bundle exec rspec spec/ I have one of my tests fail that should be passing. Here's the error:
Failure/Error: #user = Factory(:user)
NoMethodError:
undefined method `Factory' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x1037c0a70>
# ./spec/controllers/users_controller_spec.rb:21
Here's the test code:
describe "GET 'show'" do
before(:each) do
#user = Factory(:user)
end
it "should be successful" do
get :show, :id => #user
response.should be_success
end
it "should find the right user" do
get :show, :id => #user
assigns(:user).should == #user
end
end
I installed the Factory Girl gem, so I'm unsure what the issue is.
You say you installed factory_girl, but is it in both your Gemfile and Gemfile.lock files? (You may need to bundle install to get it into Gemfile.lock). Since you're using bundle exec, bundler will check your Gemfile.lock for the gems it should load.
[Edit]
On second thought, this looks like a duplicate of this SO question.
This may be not the case, but have you tried restarting the web server ?
The answers in this did not help me. What I found to solve my problem was to add a line to spec_helper.rb
require 'factory_girl'
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
Then in my spec's I would call it like so
person = build(:person)
Hope that helps someone. Was looking for about 3 hours.
I think, that this is a correct solution:
#user = Factory(:user)
Replace to
#user = Factory.create(:user)

Broken controller tests after installing Capybara?

I had a bunch of combined controller/view tests written with rspec. I added the Capybara gem and wrote some integrations tests which pass fine. The only problem is that now in all my controller tests, where I have
response.should have_selector("some selector")
rspec gives errors such as:
NoMethodError:
undefined method `has_selector?' for #<ActionController::TestResponse:0xa03e7ec>
when I run controller tests. I'm guessing that Capybara is being used in my controller tests and has overwritten some Rspec methods. How can I fix this?
# gemfile.rb
group :test do
gem 'rspec'
gem "capybara"
gem "launchy"
gem 'factory_girl_rails', '1.0'
end
# spec_helper.rb
RSpec.configure do |config|
config.include IntegrationSpecHelper, :type => :request
end
Here's an example of a failing test:
# spec/controllers/books_controller_spec.rb
require 'spec_helper'
describe BooksController do
render_views
it "should have the right page title" do
get :show, :id => #book.ean
response.should have_selector("title", :content => "Lexicase | " + #book.title)
end
end
and it's associated error:
1) BooksController GET 'show' should have the right page title
Failure/Error: response.should have_selector("title", :content => "Lexicase | " + #book.title)
NoMethodError:
undefined method `has_selector?' for #<ActionController::TestResponse:0xa8488c0>
# ./spec/controllers/books_controller_spec.rb:23:in `block (3 levels) in <top (required)>'
You were probably using Webrat earlier, and has_selector? is a Webrat matcher. Capybaras doesn't have a has_selector matcher, it has a matcher called has_css. You may want to replace the "has_selector" with "has_css".
Capybara helpers only works within requests specs. Either create a new request spec, or pass in :type => :request in the describe block part, like so:
describe "test for the testing test", :type => :request do
it "should work with capybara" do
visit root_path
click_link "Home"
page.should WHATEVA
end
end
I realize this question was asked a long time ago, but I thought I would share anyway. GLHF

Resources