ruby on rails tutorial TDD "Email has already been taken" - ruby-on-rails

I have been going through Michael Hartl's tutorial http://railstutorial.org/ and for the most part it has been a huge help in getting started with Rails. The book is very focused on TDD, which is great because I wanted to learn TDD, but the problem is 90% of my tests fail with the error "Email has already been taken". I think what is happening is that when the test runs it creates a user with email "user#example.com" as suggested in the book. The problem is when the second test runs which needs to create a user, it is using the same "user#example.com" email address. I know there are workarounds I've seen using factory girl to create a sequence of email addresses but I shouldn't have to do this to get the example from the tutorial working properly.
Has anyone else run into this problem? Judging by the lack of questions on this particular topic I am thinking it is a bug in my code but maybe someone else encountered this.

Doh! The problem was a commented line:
config.use_transactional_fixtures = true
in spec_helper.rb!
Newbie mistake.

An useful asset to clean your db for yours tests:
https://github.com/bmabey/database_cleaner

You should search on topic to how to clean database after each test. Issue may be as well caused by default user you load from fixtures and then when you create hin in the test again, but if you say 90% it seems like the first case.
I do not attach links because it makes a difference when you use rspec, test::unit or cucumber, each of them has its perks.
Happy coding!

I've had this problem recently as well. The test DB should be cleaned after tests but for some reason it wasn't. All I did was run 'rake db:reset' to reset everything and then make sure that I was using factories (Factory Girl). Just try using either fixtures or factories so you know for sure you aren't actually hitting the database.

I saw similar behavior near the end of CH 11. My spec_helper.rb was correct. This fixed it for me:
restarted "rails s"
restarted autotest
rake db:reset
rake db:migrate
rake db:test:prepare
rake db:populate
HTH,
Perry

Related

Rails spec pass example alone but fail the whole file

I have one rails spec file.
When I run: rspec my_spec.rb
There were 3 failures. These failures are in the same context.
But when I run them seperately (Example: rspec my_spec.rb:231),
they passed.
Rarely individually test also failed, if that, I restarted docker then it passed again.
I am not sure what was wrong?
I tried adding DatabaseCleaner.clean and redis.flushdb in spec_helper but no lucky.
Any idea can help?
Is very difficult to help you without the specs.But based on my own experience, usually this is a problem with hardcoded expects. Like:
expect(response.id).to eq(1)
rather then:
expect(response.id).to eq(object.id)
When you run your test only it works because of there one entity only. Check this and if it don't help, please provide us more information. Glad to help.

Rails remove persisted fixtures from tests

I used to have 3 fixtures in my RSpec tests. I have removed them and went with the FactoryGirl approach. The problem is that, when I run my tests, even though I have no trace of fixtures left, they still appear when running the tests.
If I debug the tests, I can see that the fixtures' creation date is old, older than the objects created when running the current test.
I believe fixtures are somewhere cached, how can I clear this cache? Or, if this is not the case, why are the old fixtures there when running the tests?
rake db:setup will reload your test database from your schema.rb, erasing your fixture data.
After some deep digging, I found out that some sourced files were setting an env var with the development db, not the test db. Pretty trivial mistake, but so hard to find.
As a conclusion, if others stumble upon weird problems like this one, be sure to check whether you are using the right environment variables/configuration options in your app.

Ruby on Rails Autotest No Longer Catching Errors

I am going through Hartl's rails tutorial and the autotest is no longer running newly written tests. I write a new test and it will not be reflected in autotest. Autotest still runs and remains green with a set number of examples. Existing tests will fail if I change things but new test are not recognized. Any ideas? Thanks.
Caught it. I had an errant end keyword.

Trouble with Integration Tests on Ruby on Rails Tutorial by Michael Hartl

I'm currently working through Michael Hartl's Ruby on Rails Tutorial and have made it through Chapter 8. (Really liking the tutorial by the way!) Having finished chapter 8, I've run into a snag: the final integration test in users_spec.rb is succeeding on the FIRST run, but failing on the SECOND. (You can see the section of code I'm referring to here --> http://ruby.railstutorial.org/chapters/sign-up#sec:successful_signup The error that shows up in the console is this:
1) Users signup success should make a new user
Failure/Error: response.should have_selector('div.flash.success',...
However, when looking down through all the red HTML that gets spit out, I found this:
<div id="error_explanation">
<h2>1 error
prevented this user from being saved.</h2>
<p>There were problems with the following fields:</p>
<ul>
<li>Email has already been taken</li>
</ul>
</div>
Thus it seems to me that the reason the test runs once, and THEN fails is that the user is still in the test DB on the second run and is therefore causing a validation failure due to duplicate e-mails. I can verify this by changing the e-mail in the test after each try. As long as I feed it a new email, the test won't fail.
In trying to troubleshoot further, I cloned the tutorial code from GitHub and setup the app. The tests run fine. I can run the whole suite, or just users_spec.rb as many times as I want - no problem. Actually, to be honest, (and I know this seems really odd) the code from GitHub did fail a few times with the same email duplication error, but then after I rest the test db it worked fine. Believe me, I have done this in my app as well, but I still have the same issue. And yes, I've copied and pasted in the test code directly from the book, and also from the working GitHub code in an effort to weed out typos. No deal.
It would appear that there's something outside of the users_spec.rb file itself which is causing the problem, but I can't seem to find it. I'd love to move forward with the tutorial, but for the moment I'm stuck. Any help would be appreciated!
Maybe check the config.cache_classes line in config/environments/test.rb and make sure it's true. You can also try hacking around the problem using a factory sequence.
Sounds like you need to ensure that in your spec_helper.rb, you are cleaning out your database between runs. Your users_spec is assuming that the email will not exist, and your user validations are ensuring that it is unique.
This is a decent solution: https://github.com/bmabey/database_cleaner

Rails 3 Tutorial Chapter 11 "Validation failed: Email has already been taken" error

My trouble arose in Chapter 11 of the Ruby on Rails Tutorial here.
I was seeing this rspec error:
Failure/Error: :user => Factory(:user, :email => Factory.next(:email)))
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken
first in user_spec.rb then in micropost_spec.rb. It was pretty puzzling. I thought the factory statements were generating a user in a fresh testing db each time autotest ran rspec. I checked out source files from the master branch with git and tried again, but saw the same error. I therefore suspected it related to the db contents somehow and not the code.
So, I did the following:
restarted "rails s"
restarted autotest
rake db:reset
rake db:migrate
rake db:test:prepare
rake db:populate
... and it all went green. The rspec tests passed.
There may be a more “to the point” solution, but I was thrilled this worked. Hope it helps someone else. I am left to conclude that my testing/development somehow added something to the db that was unexpected. I suppose the above steps are a good way to make yourself a fresh db near the end of chapter 11.
Was there a more direct way to solve this? Does the error indicate some other issue that I addressed without realizing it? I am left thinking that running rspec does not guarantee a fresh testing db each time. Is that a wrong assumption?
I had trouble with the Integration tests shortly after Chapter 9.4. All of my controller tests and the request integration test blew up with the message 'Email has already been taken'
What I learned from RailsTutorial - chapter 8.4.3 - Test database not clearing after adding user in integration test is that you need to do something to clean up after integration tests, because unlike unit tests they may not clean up after themselves.
The solution presented there was to use the DatabaseCleaner gem, the implementation of which is also explained in the linked Question.
I think that if you don't implement some strategy for cleaning up after the integration test you will continue to have to use your 'shotgun' solution for cleaning up the DB every time you run the test suite. Definitely not fun.
This works for me:
bundle exec rake db:test:prepare
It's also in the tutorial.
For me, the issue seemed to be running Spork. After restarting it I can run the tests as many times as I need.
It helped, added to the file factories
sequence(:email) {|n| "person#{n}#example.com" }
In my case problem was in equals emails in
factory :user
and
factory :user_with_additional_options

Resources