Rspec not finding committed changes to an object - ruby-on-rails

i'm new to rspec and ruby...
i have the following code in one of course_rspec.rb
...
it "check for active courses after enabling a course" do
course = Course.create(:title => "Testing", :description => "Testing")
course.enabled = true
course.save
active_courses = Course.where(:enabled => true)
active_courses.length.should eql 1
end
...
i get the following error
1) Course check for active courses after enabling a course
Failure/Error: active_courses.length.should eql 1
expected: 1
got: 0
(compared using eql?)
# ./course_spec.rb:86:in `block (2 levels) in <top (required)>'
why is the Course.where method return no objects? when i do this in rails console it works fine.
thanks for your help.

Are you running rails console in the test mode or in the development mode? Keep in mind that rails for testing and developing an application uses different databases.
Make sure that before the test all records are prepared and stored in the database. For this purpose you could use fixtures or factories (factory_girl for example).
ps.
Instead active_courses.length.should eql 1 you can use active_courses.should have(1).item which is more readable.

Related

Routes Increment when I Run Rspec feature

So, for some reason my routes increment by 11 when I run my comment feature test.
Exhibit A: I hit save on my comment_spec.rb
RSpec.feature "Adding comments to movies" do
before do
#kyle = Admin.create(email: "kyle#example.com", password: "password")
#jill = Member.create(email: "jill#example.com", password: "password")
#movie = Movie.create!(title: "First movie", synopsis: "Synopsis of first movie", year_released: '2000', admin: #kyle)
end
scenario "permits a signed in member to write a comment" do
login_as(#jill, scope: :member)
visit "/"
click_link #movie.title
fill_in "New Review", with: "An awesome movie"
click_button "Add Review"
expect(page).to have_content("Review has been created")
expect(page).to have_content("An awesome movie")
# must implement a nested route in order for this to work.
expect(current_path).to eq(movie_path(#movie.comments.last.id))
end
end
Then the test passes
moviesmoviesmovies/spec/features/comments_spec.rb:3)
Finished in 0.99879 seconds (files took 2.4 seconds to load) 1
example, 0 failures
Now, I hit enter in the terminal and get this:
Adding comments to movies permits a signed in member to write a comment
Failure/Error: expect(current_path).to eq(movie_path(#movie.comments.last.id))
expected: "/movies/2"
got: "/movies/4"
(compared using ==)
# ./spec/features/comments_spec.rb:26:in `block (2 levels) in <top (required)>'
Then I save the comment_spec.rb again and get this:
Adding comments to movies permits a signed in member to write a comment
Failure/Error: expect(current_path).to eq(movie_path(#movie.comments.last.id))
expected: "/movies/3"
got: "/movies/15"
(compared using ==)
# ./spec/features/comments_spec.rb:26:in `block (2 levels) in <top (required)>'
After this happens, I run:
bundle exec rails db:test:prepare
Then the tests pass again, but the above repeats. What in the world is making this happen? haha, but really?
My GitHub if needed.
The issue you're having is that your database isn't being reset after each feature test, as you likely expect it is. Specifically, the problem is with Capybara and the config.use_transactional_fixtures = true line which is set in your spec config.
Capybara effectively tests your application as an external process using a virtual browser. This means that your capybara tests only have visibility into the client-side behavior of your app (i.e. the page variable). In other words, from Capybara's perspective your app is a "Black box". Therefore, capaybara doesn't see controller objects like your session, params, or request variables, nor can it see or control the specific database transactions which occur during testing.
Rather than relying on transactional fixtures, consider using database cleaner, which manually resets the database after each feature test. You can find the gem here: https://github.com/DatabaseCleaner/database_cleaner. Make sure you follow the directions on integrating with Capybara: https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example.

Factory Girl undefined method for nil:NilClass

I have a controller spec something like this
describe :bizzaro_controller do
let(:credit_card_account) { FactoryGirl.build :credit_card_account }
it "doesn't blow up with just the stub" do
CreditCardAccount.stub(:new).and_return(credit_card_account)
end
it "doesn't blow up" do
credit_card_account
CreditCardAccount.stub(:new).and_return(credit_card_account)
end
end
Which results in this:
bizzaro_controller
doesn't blow up with just the stub (FAILED - 1)
doesn't blow up
Failures:
1) bizzaro_controller doesn't blow up
Failure/Error: let(:credit_card_account) { FactoryGirl.build :credit_card_account }
NoMethodError:
undefined method `exp_month=' for nil:NilClass
# ./spec/controllers/user/bizzareo_controller_spec.rb:5:in `block (2 levels) in <top (required)>'
# ./spec/controllers/user/bizzareo_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
Finished in 0.23631 seconds
2 examples, 1 failure
My credit card factory looks like this:
FactoryGirl.define do
factory :credit_card_account do
exp_month 10
exp_year 2075
number '3'
end
end
My CreditCardAccount is an empty ActiveRecord::Base model
=> CreditCardAccount(id: integer, exp_month: integer, exp_year: integer, number: string)
Versions
0 HAL:0 work/complex_finance % bundle show rails rspec-rails factory_girl
/home/brundage/.rvm/gems/ruby-2.0.0-p247#complex_finance/gems/rails-4.0.0
/home/brundage/.rvm/gems/ruby-2.0.0-p247#complex_finance/gems/rspec-rails-2.14.0
/home/brundage/.rvm/gems/ruby-2.0.0-p247#complex_finance/gems/factory_girl-4.2.0
This should be working. all points that your test database is not correct.
RAILS_ENV=test rake db:drop db:create will drop and recreate your test database. Then try to run your rspec using the rake command, in order to migrate the database: rake rspec
I was having the same problem, but I think the cause of my problem was different. My solution, however, may perhaps be useful: I used the Fabrication gem (http://www.fabricationgem.org/) instead of FG.
The reason why I was having this problem was because I was trying to have FG create/build an object that was not ActiveRecord, it was only an ActiveModel, and it had to be initialized with arguments.
I didn't see in the Fabricator documentation an example totally like what I needed, but I got it with this syntax:
Fabricator(:my_class) do
on_init do
init_with("Company Name", "Fake second arg")
end
end
My problem was that in model I made a private method called :send (forgot that it is already used in Ruby).

undefined method `first_name=' Rspec + Factories

I've been building my application and I'm now ready to start testing. I have Factory girl defined in seeds.rb but as I'm running tests I've also defined the tests in the usual place /spec/factories.rb for Rspec.
However my first tests fails with the following error.
user_spec.rb
require 'spec_helper'
describe User do
it "should have valid factory" do
FactoryGirl.build(:user1).should be_valid
end
end
Error returned:
Failures:
1) User should have valid factory
Failure/Error: FactoryGirl.build(:user1).should be_valid
NoMethodError:
undefined method `first_name=' for #<User:0x000000061410f8>
# ./spec/models/user_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.05459 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:4 # User should have valid factory
Randomized with seed 29084
spec/factories.rb
FactoryGirl.define do
factory :admin1, class: User do
first_name "admin"
last_name "minstrator"
password "admin1234"
profile_name "profilename"
email "admin#admin.com"
password_confirmation "admin1234"
admin true
end
factory :user1, class: User do
first_name "user2"
last_name "man2"
password "user1234"
profile_name "profilename"
email "user2#user.com"
password_confirmation "user1234"
admin false
end
end
It works fine when using the data on development in my seed.rb but now I've started testing using Rspec it has all gone wrong.
What am I doing incorrectly here. I'm not a huge fan of testing at the moment but I need to improve my skill set here as I know it can be extremely useful for web applications.
You help is greatly appreciated, please let me know if you need anymore info.
If your code works in development, but not in test, my guess is that your test copy of the database is not in sync. Try running rake db:test:prepare or rake db:test:clone and run your specs again.
Note:
db:test:clone isn't required in Rails 4.2.0 'WARNING: db:test:clone is deprecated. The Rails test helper now maintains your test schema automatically, see the release notes for details.')
I believe the issue here was that one of my migrations was missing and because it didn't have users first_name in the model there was nothing defined.
A big tip to all newbies, never ever ever delete any of your migrations.
As Homer Simpson quite rightly said "D'oh"

How to write spec for ActiveRecord

My spec/models code as require 'spec_helper'
describe Student do
it "should be work" do
student = Student.find 1
puts student.version
end
end
When running the code it shows the following error..,
Failures:
1) Student should be work
Failure/Error: student = Student.find 2
ActiveRecord::StatementInvalid:
Could not find table 'students'
# ./spec/models/student_spec.rb:6:in `block (2 levels) in <top (require
Finished in 0.00109 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/models/student_spec.rb:4 # Student should be work
I'm having students table.Also, I'm using paper_trail gem.
After running rake db:test:prepare then it shows an error as.,
Failures:
1) Student should be work
Failure/Error: s = Student.find 1
ActiveRecord::RecordNotFound:
Couldn't find Student with id=1
# ./models/student_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.02182 seconds
1 example, 1 failure
Failed examples:
rspec ./models/student_spec.rb:4 # Student should be work
It seems there is no table students in test environment, try to run
$ bundle exec rake db:test:prepare
Do you have propagated some data in your test database (using fixtures or something like FactoryGirl gem)?
Otherwise you wouldn't find any "students" in your DB.
Test-DB and Development DB have nothing in common. In fact the Test-DB will be cleared for each test.
The problem is there is no studend with id=1 in the students table of the test DB (the test DB is cleared before start new tests).
What do you want to test?
Maybe you want to use the before to insert a student at the start of the spec:
describe Student do
before do
#student = Student.new(:version => 15)
#student.save
end
it "should be work" do
student = Student.first
# Test something ...
end
end
The before block is run before every test, in this case you can get the first student in the (test) DB because you inserted it in the before block (but I don't know what you're trying to test and if save a student is really needed).

Understanding RSpec Failure

I'm getting these failures when running rspec spec/. The spec that is failing is was auto-generated with the scaffolding. I'm trying to understand RSpec but I don't know where to begin looking for the cause other than it feels like some method is missing?!? Yet, app appears to be working fine. Nothing about these failures appears in test.log. Is there another place I should be looking for hints to track this down?
$ rspec spec/
.....................F.F.
Failures:
1) clowns/edit.html.haml renders the edit clown form
Failure/Error: render
undefined method `to_sym' for nil:NilClass
# ./app/views/clowns/_form.html.haml:4:in `block in _app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/_form.html.haml:1:in `_app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/edit.html.haml:3:in `_app_views_clowns_edit_html_haml___574620942879655923_2176081980_599706797287605391'
# ./spec/views/clowns/edit.html.haml_spec.rb:13:in `block (2 levels) in <top (required)>'
2) clowns/new.html.haml renders new clown form
Failure/Error: render
undefined method `to_sym' for nil:NilClass
# ./app/views/clowns/_form.html.haml:4:in `block in _app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/_form.html.haml:1:in `_app_views_clowns__form_html_haml__3590088286240866241_2176114460_3896491916910336970'
# ./app/views/clowns/new.html.haml:3:in `_app_views_clowns_new_html_haml__1085372210838170129_2159651900_599706797287605391'
# ./spec/views/clowns/new.html.haml_spec.rb:12:in `block (2 levels) in <top (required)>'
Finished in 1.03 seconds
27 examples, 2 failures, 2 pending
And here is the spec that apparently fails (edit.html.haml_spec.rb). It was auto-generated by rails g scaffold Clown name:string balloons:integer:
#spec/views/clowns/edit.html.haml_spec.rb
require 'spec_helper'
describe "clowns/edit.html.haml" do
before(:each) do
#clown = assign(:clown, stub_model(Clown,
:name => "MyString",
:balloons => 1
))
end
it "renders the edit clown form" do
render
# Run the generator again with the --webrat-matchers flag if you want to use webrat matchers
assert_select "form", :action => clown_path(#clown), :method => "post" do
assert_select "input#clown_name", :name => "clown[name]"
assert_select "input#clown_balloons", :name => "clown[balloons]"
end
end
end
Are you also using simple_form (or perhaps even formtastic)? I get the same error when I convert the scaffold forms from standards forms to simple_form forms (form_for(#user) => simple_form_for(#user)).
It still works, as you say, so I'm not sure it's worth worrying about. I think you'd be better off just letting Cucumber worry about it. Sarah Mei says view specs are a waste of time. :-)

Resources