Rspec - PG::UndefinedTable: ERROR: relation "application" does not exist - ruby-on-rails

I'm trying to start building out and running my rspec tests using bin rails\test. They used to work a while ago, but now when I run them i'm getting the error below for every single test.
Error:
VenueTest#test_should_not_save_venue_without_name:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "application" does not exist
LINE 1: DELETE FROM "application"
^
: DELETE FROM "application"
Finished in 0.382377s, 41.8435 runs/s, 0.0000 assertions/s.
16 runs, 0 assertions, 0 failures, 16 errors, 0 skips
I've barely written any tests, so it's just the pre-rolled ones that are now failing.
I've tried running the migrations (which run fine) and the test db is definitely created. I've also tried:
rake db:test:prepare
rake db:test:load
but still getting the same error. I also don't have a model named 'application', so no idea why it's trying to delete from "application"?
I'm guessing this is some sort of weird config thing that i've messed up somewhere along the way, but have no idea what it could be!
All tests are failing, but the tests in question are:
Home_Controller_test.rb
require 'test_helper'
class HomeControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get home_index_url
assert_response :success
end
end
offers_controller_test.rb
require 'test_helper'
class OffersControllerTest < ActionDispatch::IntegrationTest
setup do
#offer = offers(:one)
end
test "should get index" do
get offers_url
assert_response :success
end
test "should get new" do
get new_offer_url
assert_response :success
end
test "should create offer" do
assert_difference('Offer.count') do
post offers_url, params: { offer: { desc: #offer.desc, end: #offer.end, offertype: #offer.offertype, start: #offer.start } }
end
assert_redirected_to offer_url(Offer.last)
end
test "should show offer" do
get offer_url(#offer)
assert_response :success
end
test "should get edit" do
get edit_offer_url(#offer)
assert_response :success
end
test "should update offer" do
patch offer_url(#offer), params: { offer: { desc: #offer.desc, end: #offer.end, offertype: #offer.offertype, start: #offer.start } }
assert_redirected_to offer_url(#offer)
end
test "should destroy offer" do
assert_difference('Offer.count', -1) do
delete offer_url(#offer)
end
assert_redirected_to offers_url
end
end
venues_controller_test.rb
require 'test_helper'
class VenuesControllerTest < ActionDispatch::IntegrationTest
setup do
#venue = venues(:one)
end
test "should get index" do
get venues_url
assert_response :success
end
test "should get new" do
get new_venue_url
assert_response :success
end
test "should create venue" do
assert_difference('Venue.count') do
post venues_url, params: { venue: { desc: #venue.desc, exists: #venue.exists, latitude: #venue.latitude, longitude: #venue.longitude, name: #venue.name, region: #venue.region, vtype: #venue.vtype } }
end
assert_redirected_to venue_url(Venue.last)
end
test "should show venue" do
get venue_url(#venue)
assert_response :success
end
test "should get edit" do
get edit_venue_url(#venue)
assert_response :success
end
test "should update venue" do
patch venue_url(#venue), params: { venue: { desc: #venue.desc, exists: #venue.exists, latitude: #venue.latitude, longitude: #venue.longitude, name: #venue.name, region: #venue.region, vtype: #venue.vtype } }
assert_redirected_to venue_url(#venue)
end
test "should destroy venue" do
assert_difference('Venue.count', -1) do
delete venue_url(#venue)
end
assert_redirected_to venues_url
end
end
EDIT
Stacktrace below as requested:
bin/rails test test/controllers/offers_controller_test.rb:18
E
Error:
VenueTest#test_should_not_save_venue_without_name:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "application" does not exist
LINE 1: DELETE FROM "application"
^
: DELETE FROM "application"
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:614:in `async_exec'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:614:in `block (2 levels) in exec_no_cache'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:46:in `block in permit_concurrent_loads'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.4/lib/active_support/concurrency/share_lock.rb:185:in `yield_shares'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:45:in `permit_concurrent_loads'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:613:in `block in exec_no_cache'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:612:in `block (2 levels) in log'
/Users/James/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:611:in `block in log'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.4/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:603:in `log'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:612:in `exec_no_cache'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:599:in `execute_and_clear'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:92:in `exec_delete'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:145:in `delete'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/query_cache.rb:17:in `delete'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:546:in `block (4 levels) in create_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:544:in `each_key'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:544:in `block (3 levels) in create_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:540:in `each'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:540:in `block (2 levels) in create_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in `block in transaction'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:194:in `block in within_new_transaction'
/Users/James/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:191:in `within_new_transaction'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in `transaction'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:538:in `block in create_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/referential_integrity.rb:22:in `disable_referential_integrity'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:523:in `create_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:1028:in `load_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:965:in `setup_fixtures'
/Users/James/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.4/lib/active_record/fixtures.rb:851:in `before_setup'
EDIT - added Venue_test.rb
require 'test_helper'
class VenueTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test "should not save venue without name" do
venue = Venue.new
assert_not venue.save, "Saved the venue without a title"
end
end

Running below command fixed this error for me:
RAILS_ENV=test rake db:test:prepare
Thanks #guy-yogev

Just in case anyone else is seeing this issue, there were extra files in the test/fixtures folder (maybe created by the generator). #dskecse identified the issue.
Once these are removed scripts run fine.

Related

How correct test anonymous controller if request action set in block subject

I test resource controller. For this I created in test anonymous controller.
I have following rspec test:
describe '#destroy' do
before { allow(controller).to receive(:custom_actions_path).and_return('/') }
subject { delete :destroy, params: { id: post.id, locale: user.language }}
it 'delete resource' do
expect { Post }.to change(Post, :count).by(-1)
end
it 'instant variables are exist' do
assigns(:resource).should_not be_nil
end
it { expect(response).to redirect_to('/') }
it { expect(response.code).to eq '302' }
end
end
Tests always falls:
1) ResourceController::Crudify#destroy delete resource
Failure/Error: expect { Post }.to change(Post, :count).by(-1)
expected `Post.count` to have changed by -1, but was changed by 0
# ./spec/unit/controllers/concerns/resource_controller/crudify_spec.rb:162:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:47:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:46:in `block (2 levels) in <top (required)>'
2) ResourceController::Crudify#destroy instant variables are exist
Failure/Error: assigns(:resource).should_not be_nil
expected: not nil
got: nil
How correct test method destroy if request to action destroy i pass in block subject? Thank you
In some cases you should call subject explicitly. Mind the first example: it should be passed to the block so RSpec can actually evaluate before and after states.
describe '#destroy' do
before { allow(controller).to receive(:custom_actions_path).and_return('/') }
subject { delete :destroy, params: { id: post.id, locale: user.language }}
it 'deletes resource' do
expect { subject }.to change(Post, :count).by(1)
end
end

NoMethodError: in Rspec

I'm currently doing rspec testing on two files and I got these failures regarding undefined methods. I need more calcification on how to exactly fixes these errors,Thanks!
Failures:
1) FavoritesController#create creates a favorite for the current user and specified post
Failure/Error: #post = create(:post)
NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::FavoritesController::Create:0x007fdabc84f7f8>
# /Users/bryanporras/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.1/lib/action_dispatch/testing/assertions/routing.rb:171:in `method_missing'
# ./spec/controllers/favorites_controller_spec.rb:8:in `block (2 levels) in <top (required)>'
2) FavoritesController#destroy destroys the favorite for the current user and post
Failure/Error: #post = create(:post)
NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::FavoritesController::Destroy:0x007fdabfe0f3e8>
# /Users/bryanporras/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.1/lib/action_dispatch/testing/assertions/routing.rb:171:in `method_missing'
# ./spec/controllers/favorites_controller_spec.rb:8:in `block (2 levels) in <top (required)>'
3) VotesController#up_vote adds an up-vote to the post
Failure/Error: sign_in #user
NoMethodError:
undefined method `sign_in' for #<RSpec::ExampleGroups::VotesController::UpVote:0x007fdabfe26fe8>
# /Users/bryanporras/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.1/lib/action_dispatch/testing/assertions/routing.rb:171:in `method_missing'
# ./spec/controllers/votes_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
4) Vote after_save calls `Post#update_rank` after save
Failure/Error: vote = Vote.new(value: 1, post: post)
NameError:
undefined local variable or method `post' for #<RSpec::ExampleGroups::Vote::AfterSave:0x007fdabdb8b0b0>
# ./spec/models/vote_spec.rb:25:in `block (3 levels) in <top (required)>'
Finished in 0.78639 seconds (files took 2.82 seconds to load)
15 examples, 4 failures, 2 pending
Failed examples:
rspec ./spec/controllers/favorites_controller_spec.rb:14 # FavoritesController#create creates a favorite for the current user and specified post
rspec ./spec/controllers/favorites_controller_spec.rb:24 # FavoritesController#destroy destroys the favorite for the current user and post
rspec ./spec/controllers/votes_controller_spec.rb:8 # VotesController#up_vote adds an up-vote to the post
rspec ./spec/models/vote_spec.rb:24 # Vote after_save calls `Post#update_rank` after save
This is the favorites_controller_spec.rb file:
require 'rails_helper'
describe FavoritesController do
include Devise::TestHelpers
before do
#post = create(:post)
#user = create(:user)
sign_in #user
end
describe '#create' do
it "creates a favorite for the current user and specified post" do
expect( #user.favorites.find_by(post_id: #post.id) ).to be_nil
post :create, { post_id: #post.id }
expect( #user.favorites.find_by(post_id: #post.id) ).not_to be_nil
end
end
describe '#destroy' do
it "destroys the favorite for the current user and post" do
favorite = #user.favorites.where(post: #post).create
expect( #user.favorites.find_by(post_id: #post.id) ).not_to be_nil
delete :destroy, { post_id: #post.id, id: favorite.id }
expect( #user.favorites.find_by(post_id: #post.id) ).to be_nil
end
end
end
and this is the votes_controller_spec.rb file:
require 'rails_helper'
describe VotesController do
include TestFactories
describe '#up_vote' do
it "adds an up-vote to the post" do
request.env["HTTP_REFERER"] = '/'
#user = authenticated_user
#post = associated_post
sign_in #user
expect {
post( :up_vote, post_id: #post.id )
}.to change{ #post.up_votes }.by 1
end
end
end
Check if you have config.include FactoryGirl::Syntax::Methods inside rails_helper.rb
If you have above line in rails_helper.rb file you can always use FactoryGirl.create :user
You didn't probably include include Devise::TestHelpers in specs for VotesController that's why it does not see sign_in method

Failing uniqueness validation with FactoryGirl

I'm having problems with FactoryGirl, I'm using sequence to avoid duplicating fields, but validations are failing anyway.
Output:
1) CustomersController anonymous user GET #edit is redirected to signin when accessing edit form
Failure/Error: get :edit, id: create(:customer)
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken, Email has already been taken
# ./spec/controllers/customers_controller_spec.rb:25:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
3) Customer public class methods executes its methods correctly #find_by_id_or_name finds customer by name
Failure/Error: let(:john) {create(:customer, name: 'John Doe X')}
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken, Email has already been taken
# ./spec/models/customer_spec.rb:25:in `block (3 levels) in <top (required)>'
# ./spec/models/customer_spec.rb:38:in `block (5 levels) in <top (required)>'
# -e:1:in `<main>'
Factories:
FactoryGirl.define do
factory :customer do
user
name {Faker::Name.name}
sequence(:mail) { |n| "person#{n}#example.com" }
address {Faker::Address.street_address}
phone {Faker::PhoneNumber.phone_number}
end
end
FactoryGirl.define do
factory :user do
sequence(:email) {|i| "example#{i}#example.com"}
password {Faker::Internet.password(10)}
end
end
These are the tests that are failing:
RSpec.describe Customer, type: :model do
describe "public class methods" do
let(:john) {create(:customer, name: 'John Doe X')}
let(:frank) {create(:customer)}
context "responds to its methods" do
it "responds to #find_by_id_or_name" do
expect(Customer).to respond_to(:find_by_id_or_name)
end
end
context "executes its methods correctly" do
context "#find_by_id_or_name" do
it "finds customer by name" do
customer = Customer.find_by_id_or_name('John Doe X')
expect(customer).to eq john
end
it "finds customer by id" do
customer = Customer.find_by_id_or_name(frank.id)
expect(customer).to eq frank
end
end
end
end
end
RSpec.describe CustomersController, type: :controller do
context "signed in user" do
before :each do
#user = create(:user)
end
describe "GET #edit" do
it "renders :edit view" do
get :edit, id: create(:customer).id
expect(response).to render_template(:edit)
end
end
describe "DELETE #destroy" do
before :each do
#customer = create(:customer, user: #user)
end
it "deletes record" do
expect {delete :destroy, id: #customer.id}.to change(Customer, :count).by(-1)
end
end
end
end
This is happening to me all over my app. I just copied some tests that apply to Customer.
Thanks
My problem was related to not appropiately configuring database_cleaner. The configuration in this post solves the problem: How can I clean my database between erroneous rspec specs?

Post request in controller specs

I have problem with testing my controller. I've test post request in 2 context. With valid attributes and with invalid attributes. I have problem with valid attributes context.
I have the following test:
describe "POST #create" do
context "with valid attributes" do
it "saves the new car_configuration in the database" do
expect{
post :create, car_configuration: attributes_for(:car_configuration)
}.to change(CarConfiguration, :count).by(1)
end
it "redirects to the index car_configuration" do
post :create, car_configuration: attributes_for(:car_configuration)
should redirect_to admin_car_configurations_url
end
end
end
And my car_configuration factory is:
FactoryGirl.define do
factory :car_configuration do
sequence(:image) {|n| "Image #{n}"}
small_cases_count 5
big_cases_count 2
association :body_style, factory: :car_body_style
association :model, factory: :car_model
association :car_class
end
end
And errors that rspec shows:
1) Admin::CarConfigurationsController POST #create with valid attributes saves the new car_configuration in the database
Failure/Error: expect{
count should have been changed by 1, but was changed by 0
# ./spec/controllers/admin/car_configurations_controller_spec.rb:42:in `block (4 levels) in <top (required)>'
2) Admin::CarConfigurationsController POST #create with valid attributes redirects to the index car_configuration
Failure/Error: should redirect_to admin_car_configurations_url
Expected response to be a <redirect>, but was <200>
# ./spec/controllers/admin/car_configurations_controller_spec.rb:49:in `block (4 levels) in <top (required)>'
spec/controllers/admin/car_configuratoins_controller_spec.rb
require 'spec_helper'
describe Admin::CarConfigurationsController do
let(:configuration) { build :configuration }
context "POST create" do
it "creates a config" do
expect { perform }.to change(CarConfiguration, :count).by(1)
end
def perform
post :create, car_configuration: configuration.attributes
end
end
end

FactoryGirl::InvalidFactoryError Controller Spec

I'm trying to create a controller spec for a contact form. All I want is to test that the :new template is rendered when invalid attributes are submitted. I've tried various configurations of the factory, as well as changing it to a trait, instead of factory to no avail. The error message doesn't get very specific, just Invalid Factory. Any ideas would be appreciated!
# blog_app/spec/factories/inquiries.rb
FactoryGirl.define do
factory :inquiry do
name "TestName"
email "test#test.com"
phone "123-456-7890"
message "TestMessage"
end
factory :invalid_inquiry, parent: :inquiry do
name nil
end
end
#/app/controllers/inquiries_controller.rb
class InquiriesController < ApplicationController
def new
#inquiry = Inquiry.new
end
def create
#inquiry = Inquiry.new(params[:inquiry])
if #inquiry.deliver
render :thank_you
else
render :new
end
end
end
# spec/controllers/inquiries_controller_spec.rb
require 'spec_helper'
describe InquiriesController do
it "has a valid factory" do
FactoryGirl.build(:inquiry).should be_valid
end
describe "POST #create" do
context "with valid attributes" do
it "delivers inquiry" #pending
it "renders the :thank_you page template" do
post :create, inquiry: FactoryGirl.attributes_for(:inquiry)
response.should render_template :thank_you
end
end
context "with invalid attributes" do
it "does not deliver inquiry" do #pending
it "renders :new page template" do
post :create, inquiry: FactoryGirl.attributes_for(:invalid_inquiry)
response.should render_template :new
end
end
end
describe "GET #new" do
it "renders :new page template" do
get :new
response.should render_template :new
end
end
end
Finished in 0.31244 seconds
0 examples, 0 failures
/Users/.../.rvm/gems/ruby-2.0.0-p353/gems/factory_girl-4.4.0/lib/factory_girl.rb:73:in `lint': The following factories are invalid: (FactoryGirl::InvalidFactoryError)
* invalid_inquiry
from /Users/.../Documents/blog_app/spec/support/factory_girl.rb:8:in `block (2 levels) in <top (required)>'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:21:in `instance_eval'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:21:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:66:in `block in run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:66:in `each'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:66:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/hooks.rb:418:in `run_hook'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/command_line.rb:27:in `block in run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/reporter.rb:34:in `report'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/command_line.rb:25:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:80:in `run'
from /Users/.../.rvm/gems/ruby-2.0.0-p353/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:17:in `block in autorun'
Does this work?
FactoryGirl.define do
factory :inquiry do
name "TestName"
email "test#test.com"
phone "123-456-7890"
message "TestMessage"
factory :invalid_inquiry do
name nil
end
end
end
Alternatively you might try replacing:
post :create, inquiry: FactoryGirl.attributes_for(:invalid_inquiry)
with:
post :create, inquiry: FactoryGirl.attributes_for(:inquiry, name: nil)
and getting rid of the invalid_inquiry factory altogether.

Resources