record generated by FactoryGirl disappears in rspec - ruby-on-rails

We are running a spec (3.4.4) with Rails 4.2.0. Here is the spec:
it "returns http success" do
proj = FactoryGirl.create(:ext_construction_projectx_project, :name => 'namenewnew')
get 'new' , {:project_id => proj.id}
expect(response).to be_success
end
In debug, proj.id is 3 and all its values are correct. ExtConstructionProjectx::Project.find(3) returns nil and ExtConstructionProjectx::Project.count returns 0. The project record just disappears.
Is it possible that the rspec did not see the project record created on its db connection? How to fix this problem?
Update:
Here is the gemspec
s.add_dependency "rails", ">=4.2.0"
s.add_dependency "jquery-rails"
s.add_dependency "simple_form"
s.add_dependency "will_paginate"
s.add_dependency "database_cleaner"
s.add_dependency "execjs"
s.add_dependency "sass-rails", '~>5.0.1'
s.add_dependency "coffee-rails", '~>4.1.0'
s.add_dependency "uglifier"
s.add_development_dependency "sqlite3"
s.add_development_dependency "rspec-rails", ">= 3.2.0"
s.add_development_dependency "factory_girl_rails", '~>4.5'
s.add_development_dependency 'capybara'
s.add_development_dependency 'launchy'
Also in rails_spec, there is:
config.use_transactional_fixtures = true

This is expected behavior. If database records persisted between test calls, your testing wouldn't be isolated or properly test each case.
If you don't want the current behavior:
Consider removing (or reconfiguring) the database_cleaner gem.
Set config.use_transactional_fixtures = false in your rspec configuration. Or review the rspec docs for another strategy.
The "better" solution:
Rewrite your tests such that they do not depend on state from earlier test runs.
Consider using before(:each) and before(:all) macros in your rspec tests.

Related

Why are helper methods not working in view specs?

I have a conditional in my view based upon a helper method defined in my application controller, which I defined as a helper method.
<% if logged_in? %>
When my spec hits this, it says:
ActionView::Template::Error:
undefined method `logged_in?' for #<#<Class:0x007fdc06b71aa8>:0x007fdc0b9b0930>
When I use my browser, it works perfect. I tried stubbing it, but I get another error when I try to stub it on the view or controller. This is what my test looks like:
it "has a logout link" do
render
expect(rendered).to have_link "Logout"
end
Here's my gemfile:
ruby "2.4.1"
gem "bootsnap", ">= 1.1.0", require: false
gem "coffee-rails", "~> 4.2"
gem "jbuilder", "~> 2.5"
gem "pg"
gem "puma", "~> 3.11"
gem "rails", "~> 5.2.1"
gem "rails-controller-testing"
gem "sass-rails", "~> 5.0"
gem "turbolinks", "~> 5"
gem "uglifier", ">= 1.3.0"
group :development, :test do
gem "byebug", platforms: %i[mri mingw x64_mingw]
end
group :development do
gem "listen", ">= 3.0.5", "< 3.2"
gem "spring"
gem "spring-watcher-listen", "~> 2.0.0"
gem "web-console", ">= 3.3.0"
end
group :test do
gem "capybara", ">= 2.15"
gem "chromedriver-helper"
gem "factory_bot_rails"
gem "rspec-rails", "~> 3.7"
gem "selenium-webdriver"
gem "shoulda-matchers", "~> 3.1"
end
Update to the accepted answer, it now seems necessary to use without_partial_double_verification to get around the ActionView::Base does not implement: field_name error.
Example code:
let(:logged_in) { true }
before(:each) do
without_partial_double_verification do
allow(view).to receive(:logged_in?).and_return(logged_in)
end
render
end
it 'has a logout link' do
expect(rendered).to have_link 'Logout'
end
context 'with no logged user' do
let(:logged_in) { false }
it 'has a login link' do
expect(rendered).to have_link 'Login'
end
end
View specs usually does not need to call the real helper (if you wan't to test the helper then you can do a helper spec).
It's faster and easier to just stub the helper method to return the value you want for your given test:
context 'with a logged user' do
before(:each) do
allow(view).to receive(:logged_in?).and_return(true)
end
it 'has a logout link' do
render
expect(rendered).to have_link 'Logout'
end
end
context 'with no logged user' do
before(:each) do
allow(view).to receive(:logged_in?).and_return(false)
end
it 'has a login link' do
render
expect(rendered).to have_link 'Login'
end
end
When you do model, controller, views, helper or any other isolated test, it does not have access to all the app since it's designed to run fast. For example: controller tests does not render views by default, model specs only tests the model, view specs do not have a context of the request nor session, etc.
You can have full real user tests using integration (feature) specs which runs the whole user interaction from beginning to end with access to everything, even controlling what the user clicks.

Cucumber inconsistent behaviour

I am trying to run test features."bundle exec cucumber features" starts failing abnormally(during login itself),it fails to recognize an existing user. while it works fine if i run individual feature files. What am i doing wrong?
Gem File:
group :test do
gem 'ruby-prof'
gem 'cucumber-rails', :require => false
gem 'cucumber'
gem 'spork'
gem 'launchy'
gem 'capybara'
gem 'selenium-webdriver'
gem 'selenium-client'
gem 'database_cleaner'
gem 'email_spec', :branch=>'rails3'
end
In env.rb
begin
DatabaseCleaner.strategy = :transaction
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end

capybara with :js => true very slow

when I toggle :js => true on my examples, takes too long very long to come up and run the first test, then becomes acceptable peformance
this sample running in 0.36722 seconds without :js, and 58.15 seconds with :js => true
require 'spec_helper'
include UserAbilitiesHelper
describe "Customer Task Pages" do
subject { page }
describe "side panel with the history of the tasks related to customer" do
before do
visit root_path()
end
it { sould have_content(I18n.t("customers.tasks.side.title")) }
end
describe "side panel with the history of the tasks related to customer" do
before do
visit root_path()
end
it { sould have_content(I18n.t("customers.tasks.side.title")) }
end
end
my Gemfile
source 'https://rubygems.org'
gem 'rails', '3.2.5'
gem 'pg', '0.12.2'
gem "meta_search"
# Bootstrap and layouting
gem 'bootstrap-sass', '2.0.3'
gem 'will_paginate', '3.0.3'
gem 'bootstrap-will_paginate', '0.0.6'
gem 'rails3-jquery-autocomplete'
#test support
gem 'faker', '1.0.1'
#login rules
gem 'devise'
gem 'cancan'
#criptar
gem 'bcrypt-ruby', '3.0.1'
#BR
gem 'brazilian-rails'
gem 'rails-i18n'
group :development do
gem 'annotate', '~> 2.4.1.beta'
gem 'nested_scaffold'
end
group :development, :test do
gem 'rspec-rails', '2.10.0'
gem 'guard-rspec', '0.5.5'
gem 'guard-spork', '0.3.2'
gem 'spork', '0.9.0'
gem 'ruby-debug19'
gem 'linecache19'
gem 'factory_girl_rails', '1.4.0'
end
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '3.2.4'
gem 'coffee-rails', '3.2.2'
gem 'uglifier', '1.2.3'
end
gem 'jquery-rails', '2.0.0'
group :test do
gem 'capybara', '1.1.2'
gem "launchy"
gem 'ZenTest'
#MAC OS Especific
gem 'rb-fsevent', '0.4.3.1', :require => false
gem 'growl', '1.0.3'
#Cucumber
gem 'cucumber-rails', '1.2.1', require: false
gem 'database_cleaner', '0.7.0'
end
group :production do
#gem 'pg', '0.12.2'
end
running with
bundle exec rspec
An example any
Bruno-Guerras-MacBook-Pro:railstutorial brunoguerra$ bundle exec rspec spec/requests/authentication_pages_spec.rb
No DRb server is running. Running in local process instead ...
WARNING: Nokogiri was built against LibXML version 2.7.8, but has dynamically loaded 2.7.3
.....................
Finished in 6.07 seconds
21 examples, 0 failures
Bruno-Guerras-MacBook-Pro:railstutorial brunoguerra$ bundle exec rspec spec/requests/authentication_pages_spec.rb
No DRb server is running. Running in local process instead ...
WARNING: Nokogiri was built against LibXML version 2.7.8, but has dynamically loaded 2.7.3
............F........
Failures:
1) Authentication authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page
Failure/Error: page.should have_selector('title', text: 'Edit user')
expected css "title" with text "Edit user" to return something
# ./spec/requests/authentication_pages_spec.rb:65:in `block (6 levels) in <top (required)>'
Finished in 1 minute 14.18 seconds
21 examples, 1 failure
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:64 # Authentication authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page
Bruno-Guerras-MacBook-Pro:railstutorial brunoguerra$
thanks
I discovery, my dns server is too slow, I changed my dns server and the problem solved, another thing I did to improve the speed of testing was to configure these parameters webrick
configure webrik speedup but, its solve the same problem, DNS server! urgh!!!
You can also try changing the driver :webkit_debug and then rerun your specs to see any if there are any scripts that don't need to be loaded on the page.
Capybara.javascript_driver = :webkit_debug
Then add any urls to the black list
config.before(:each, js: true) do
page.driver.browser.url_blacklist = ["http://use.typekit.net"]
end

How do I setup rspec with rails 2.3.8 and bundler?

A lot of the guides I've been finding don't use bundler.
this is the part of the gemfile I'm using for tests:
group :test do
gem "cucumber"
gem "cucumber-rails"
gem "launchy"
gem "hpricot"
gem "gherkin"
gem "capybara"
gem "rspec"
gem "rack"
gem "rspec-rails"
gem "webrat"
gem "database_cleaner"
gem "factory_girl"
gem "shoulda", :require => nil
gem "shoulda-matchers", :git => "https://github.com/thoughtbot/shoulda-matchers"
gem "cobravsmongoose"
gem "rcov"
gem "ZenTest"
gem "autotest-growl"
gem "inherited_resources", "1.0.2"
gem "responders", "0.4.2"
end
But even with all that, the generators never exist.
so doing: script/generate rspec
doesn't work, (can't find the rspec) generator
generators would be installed if the gems were installed as plugins... but I think that just adds bloat to the app, and different gems compile differently on different OSes.
So, anyone have any guides for setting up rspec with bundler with rails 2.3.x?
Setting up RSpec, Guard, and Spork on a Rails 2 project
I've done this a few times now; hopefully this will be helpful to anyone needing to maintain Rails 2.3 apps. This has worked great for the apps I've worked on, but I welcome contributions from others who suggest additional steps.
This guide assumes a Rails 2.3.x project on Bundler
Get rid of any old rspec plugins that are in your project, if any. RSpec bits may be hiding in:
Rakefile
lib/tasks/rspec.rake
vendor/plugins/rspec
(anything else you can find)
RSpec 2 is not compatible with Rails 2; use RSpec 1 (docs). Put the most recent compatible gem versions to your Gemfile:
group :test, :development do
gem 'test-unit', '1.2.3', :require => false # for rspec
gem 'rspec', '~> 1.2', :require => false
gem 'rspec-rails', '~> 1.2', :require => false
gem 'guard', :require => false
gem 'spork', '~> 0.8.0', :require => false
gem 'guard-rspec', :require => false
gem 'guard-spork', :require => false
gem 'growl', :require => false # notifications; optional
gem 'rb-fsevent', :require => false # for OSX; optional
gem 'listen', '>= 0.5.1', :require => false
gem 'machinist', '~> 2.0', :require => false
gem 'database_cleaner', '~> 0.9.1', :require => false
end
The :require => false options are optional, but it helps the app to start up faster in development if it doesn't have to load testing libraries outside of when SpecHelper.rb requires them.
Install the bundle. Use bundle update for any gems that were already in your Gemfile.
Ensure lib/tasks/rspec.rake and spec/spec_helper.rb do not exist.
script/generate rspec
Remove the config.gem line that was added to config/environments/test.rb; the app uses bundler.
spork --bootstrap
Then edit spec/spec_helper.rb and follow the instructions.
Move everything from the stock spec_helper.rb into the prefork block, except:
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
belongs in each_run.
Install database_cleaner. In spec/spec_helper.rb,
In the prefork block:
require 'database_cleaner'
In the each_run block:
DatabaseCleaner.clean
Initialize Guardfile
guard init spork
guard init rspec
Modify the Guardfile's rspec guard to use the correct version and drb (spork):
guard 'rspec', :version => 1, :cli => '--drb --color' do
Modify the Guardfile as appropriate for your project
Run rake spec. You should get no output (if you have no tests). If you get errors, resolve them.
Run guard. No errors? Great, test away!
Problems? Try again more quickly by running spec spec instead of re-running guard.
We still have an app on rails 2.3.8, but we updated it to use bundler (Gemfile), and it has rspec and cucumber working as well.
Make sure you follow the bundler guide to make your app correctly use the Gemfile's gem loading instead of Rails' default: http://gembundler.com/rails23.html
After you get that preinitializer.rb and change the config/boot.rb working correctly, you might need to make sure you're using the right versions of rspec and cucumber.
I think just that generic gem 'rspec-rails' might try installing rspec 2 for you, but that only works on Rails 3 (I believe), so you might need to specifically tell it to use rspec 1.x.
Our test group looks like this (although I think some of these gems may be older than they need to be, it's been awhile since we've updated them since a rails 3 upgrade for the app is pending we're not too worried about what it looks like right now):
group :test, :cucumber do
gem 'autotest-fsevent'
gem 'test-unit', '~>1.2.3'
gem "hoe", "1.5.1"
gem 'autotest-rails', '4.1.0'
gem 'rspec', '1.3.2'
gem 'rspec-rails', '1.3.4'
gem 'cucumber', '0.10.0'#, '0.9.0'
# Change this shinanigans to 0.4.0 when it gets released ;)
gem 'cucumber-rails', '0.3.2'
gem 'database_cleaner', '0.5.2'
gem 'capybara', '0.3.9'
gem 'launchy'
gem 'dupe', '0.5.1'
gem 'factory_girl', '1.2.4'
gem 'email_spec', '~>0.6.2', :require => false
end
After doing this, and running bundle install, I am able to type the command script/generate --help which includes this in the output:
Installed Generators
Rubygems: business_time_config, cucumber, culerity, dupe, email_spec, feature, integration_spec, paperclip, rspec, rspec_controller, rspec_model, rspec_scaffold
Builtin: controller, helper, integration_test, mailer, metal, migration, model, observer, performance_test, plugin, resource, scaffold, session_migration
As you can see, the cucumber and rspec generators are in fact available there.
I think your problem might be the version of rspec it's installing. If it's installing rspec version 2, then that is tied to rails 3, which handles generators in gems differently I believe (I believe they have to be put in a different directory structure). That could be why your rails 2.3.x app isn't seeing them.
You don't have to follow my versions exactly, I'm not a fan (at all) of putting specific versions in a Gemfile but we ended up doing it here way back when because a) we didn't fully understand bundler, and b) We needed to make sure we were getting rails 2.3-compatible gems.
Hopefully this helps! Let me know if you have questions.
The reason the generators don't exist is that when you run rails generate ..., it's executing in the development environment while these gems are only loaded in the test environment.
Option 1
Add them to both development and test environments.
Option 2
Run rails generate ... RAILS_ENV=test
(I'm not positive that this option will work.)
In rails 5.1.4 you there are four easy steps to get your RSpec up and running:
group :development, :test do
gem "database_cleaner"
gem "rspec-rails"
end
Add the above gems to the :test and :development groups in your Gemfile.
run bundle install from the command line
run rails generate rspec:install from the command line, it will create the following files:
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
configure spec_helper.rb and rails_helper.rb
You can check more detailed info on: https://kolosek.com/rails-rspec-setup.

No such factory: user (ArgumentError) but... it is defined. and using find_definitions() just finds duplicates... =\

So, I recently moved to bundler, and I'm having issues getting everything working again.
when I run bundle exec rake test:units, I get this error:
....../gems/factory_girl-1.2.4/lib/factory_girl/factory.rb:327:in `factory_by_name': No such factory: user (ArgumentError)
and, I saw in a another stack overflow post that someone fixed the problem by adding
FactoryGirl.find_definitions
but, that errors in saying that I have duplicate definitions (which I don't, cause search)
I even tried having only one factories file. but the error continued.
top of test_helper:
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'test_help'
require "bundler/setup"
Bundler.require(:test)
test group in gem file
group :test do
gem "cucumber", "~>0.10.3"
gem "cucumber-rails", "0.3.2"
gem "launchy"
gem "hpricot"
gem "gherkin", "~>2.4.0"
gem "capybara", "0.4.1.2"
gem "rspec", "1.3.2"
gem "rspec-rails", "1.3.2"
gem "rspec-core"
gem "rspec-expectations"
gem "webrat", "0.7.0"
gem "database_cleaner"
gem "factory_girl", "1.2.4"
gem "shoulda"
gem "awesome_print"
gem "cobravsmongoose"
end

Resources