Why is my rspec test not working?

Here's the test:

describe "admin attribute" do before(:each) do @user = User.create!(@attr) end it "should respond to admin" do @user.should respond_to(:admin) end it "should not be an admin by default" do @user.should_not be_admin end it "should be convertible to an admin" do @user.toggle!(:admin) @user.should be_admin end end 

Here's the error:

  1) User password encryption admin attribute should respond to admin Failure/Error: @user = User.create!(@attr) ActiveRecord::RecordInvalid: Validation failed: Email has already been taken # ./spec/models/user_spec.rb:128 

I think the error may be somewhere in my data code for data:

 require 'faker' namespace :db do desc "Fill database with sample data" task :populate => :environment do Rake::Task['db:reset'].invoke admin = User.create!(:name => "Example User", :email => " example@railstutorial.org ", :password => "foobar", :password_confirmation => "foobar") admin.toggle!(:admin) 99.times do |n| name = Faker::Name.name email = "example-#{n+1}@railstutorial.org" password = "password" User.create!(:name => name, :email => email, :password => password, :password_confirmation => password) end end end 

Please let me know if I will play more of my code.

UPDATE: here, where @attr is defined at the top of the user_spec.rb file:

 require 'spec_helper' describe User do before(:each) do @attr = { :name => "Example User", :email => " user@example.com ", :password => "foobar", :password_confirmation => "foobar" } end 
+4
source share
4 answers

Make sure that the user_spec.rb block that invokes User.create in the before(:each) block with the same email address is not already blocked. If your blocks are nested incorrectly, you will get this error. For example, in a Rails tutorial, it's easy to accidentally embed your describe "admin attribute" into your describe "password encryption" block, which uses the same before(:each) code.

+6
source

Try checking existing users in the previous block:

 before(:each) do User.count.should == 0 @user = User.create!(@attr) end 

If this fails, another user exists with the same email address. This may be due to the fact that another user created the user with the same attributes before the block or that the test database was incorrectly cleaned after a failure. In the latter case, try running rake db:test:prepare , and then run the spec again.

+2
source

before( :each ) is going to create a new custom object from @attr. Therefore, if @attr does not change the values ​​for its fields, and you turned on checks to prevent duplication, then in the second test, the user object created in the first test will encounter the one you are trying to create in the 2nd test.

There are other ways to test your model without a database. For example, you can use test twins to create and configure objects exactly with the data you want, and then run your test to make sure that it behaves correctly. There is a great book about RSpec, Cucumber, and BDD that can be a great source.

Edit: Sorry, I'm confusing before(:each) with before(:all) .

0
source

This is not an ideal way to set up test data. those. using the rake task to populate the database.

More standard unit testing and Rails practice would be to use factory_girl or test_fixture and transactional test equipment or database_cleaner gem.

Read a little about it, and they should be straightforward to use. They ensure that each of your rspec tests runs in isolation, even when you run everything together. Thus, each test file for one test will not affect the other.

0
source

Source: https://habr.com/ru/post/1341492/


All Articles