2013-01-20 67 views
0

我正在閱讀Michael Hartl的rails教程,並在第10.1.4章中獲得了spec驗證錯誤,即使我認爲我遵循了這些說明。Rails教程第10.1.4章:「用戶已經被使用」

我是Rails的新手,但它看起來像工廠女孩試圖創建一個已經存在的用戶,即使下面的代碼應該創建一個新的微柱,並將其分配給現有用戶:

FactoryGirl.create(:micropost,user:@user,created_at:1.hour.ago)

有誰知道如何解決錯誤?

錯誤

1)用戶關聯微柱應該具有以正確的次序 故障/錯誤的權利微柱:FactoryGirl.create(:微柱,用戶:@user,created_at:1.hour.ago) 的ActiveRecord :: RecordInvalid: 驗證失敗:用戶已經採取 #./spec/models/user_spec.rb:159

2)用戶協會微柱破壞應該相關的微柱 故障/錯誤:FactoryGirl.create( :微博,用戶:@user, created_at:1.hour.ago) 的ActiveRecord :: RecordInvalid: 驗證失敗:用戶已經採取 #./spec/models/user_spec.rb:159

user_spec.rb

require 'spec_helper' 

describe User do 

    before do 
    @user = User.new(name: "Example User", email: "[email protected]", 
     password: "foobar", password_confirmation: "foobar") 
    end 

    subject { @user } 

    it { should respond_to(:name) } 
    it { should respond_to(:email) } 
    it { should respond_to(:password_digest) } 
    it { should respond_to(:password) } 
    it { should respond_to(:password_confirmation) } 
    it { should respond_to(:remember_token) } 
    it { should respond_to(:authenticate) } 
    it { should respond_to(:admin) } 
    it { should respond_to(:authenticate) } 
    it { should respond_to(:microposts) } 

    it { should be_valid } 
    it { should_not be_admin } 

    describe "when name is not present" do 
    before { @user.name = " " } 
    it { should_not be_valid } 
    end 

    describe "when email is not present" do 
    before { @user.email = " " } 
    it { should_not be_valid } 
    end 

    describe "when name is too long" do 
    before { @user.name = "a" * 51 } 
    it { should_not be_valid } 
    end 

    describe "when email format is invalid" do 
    it "should be invalid" do 
     addresses = %w[[email protected],com user_at_foo.org [email protected] 
         [email protected]_baz.com [email protected]+baz.com] 
      addresses.each do |invalid_address| 
      @user.email = invalid_address 
      @user.should_not be_valid 
     end  
     end 
    end 

    describe "when email is not downcase" do 
    let(:uppercase_email) { "[email protected]"} 

    it "should be set to downcase" do 
     @user.email = uppercase_email 
     @user.save 
     @user.email.should == uppercase_email.downcase 
    end 
    end 

    describe "when email format is valid" do 
     it "should be valid" do 
     addresses = %w[[email protected] [email protected] [email protected] [email protected]] 
     addresses.each do |valid_address| 
      @user.email = valid_address 
      @user.should be_valid 
     end  
    end 
    end 

    describe "when email address is already taken" do 
    before do 
     user_with_same_email = @user.dup 
     user_with_same_email.email.upcase! 
     user_with_same_email.save 
     end 

     it { should_not be_valid } 
    end 

    describe "when password is not present" do 
    before { @user.password = @user.password_confirmation = " " } 
    it { should_not be_valid } 
    end 

    describe "when password doesn't match confirmation" do 
    before { @user.password_confirmation = "mismatch" } 
    it { should_not be_valid } 
    end 

    describe "when password confirmation is nil" do 
    before { @user.password_confirmation = nil } 
    it { should_not be_valid } 
    end 

    describe "return value of authenticate method" do 
     before { @user.save } 
     let(:found_user) { User.find_by_email(@user.email) } 

    describe "with valid password" do 
     it { should == found_user.authenticate(@user.password) } 
    end 

    describe "with invalid password" do 
     let(:user_for_invalid_password) { found_user.authenticate("invalid") } 

     it { should_not == user_for_invalid_password } 
     specify { user_for_invalid_password.should be_false } 
     end  
    end 

    describe "with a password that's too short" do 
    before { @user.password = @user.password_confirmation = "a" * 5 } 
    it { should be_invalid } 
    end 

    describe "remember token" do 
    before { @user.save } 
    its(:remember_token) { should_not be_blank } 
    end 

    describe "with admin attribute set to 'true'" do 
     before do 
     @user.save! 
     @user.toggle!(:admin) 
     end 

     it { should be_admin } 
    end 

    describe "confirm admin attribute is not accessible" do 
     it "should not be accessible" do 
      expect do 
       @user.update_attributes(:admin => true) 
     end.to raise_error(ActiveModel::MassAssignmentSecurity::Error) 
    end 
    end 

    describe "micropost associations" do 

    before { @user.save } 
    let!(:older_micropost) do 
     FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) 
    end 

    let!(:newer_micropost) do 
     FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago) 
    end 

    it "should have the right microposts in the right order" do 
     @user.microposts.should == [newer_micropost, older_micropost] 
    end 

    it "should destroy associated microposts" do 
     microposts = @user.microposts.dup 
     @user.destroy 
     microposts.should_not be_empty 
     microposts.each do |micropost| 
     Micropost.find_by_id(micropost.id).should be_nil 
     end 
    end 
    end 
end 

factories.rb

FactoryGirl.define do 
    factory :user do 
    # Rails::logger.info "hello" 

    sequence(:name) { |n| "Person #{n}" } 
    sequence(:email) { |n| "person_#{n}@example.com" } 
    password "foobar" 
    password_confirmation "foobar" 

    factory :admin do 
     admin true 
    end 
    end 

    factory :micropost do 
    content "Lorem ipsum" 
    user 
    end 
end 

回答

1

您沒有使用FactoryGirl在那裏創建一個用戶對象。在靠近user_spec.rb的頂部,以@user的分配開始@user = User.new...而是應該是這樣的:

@user = FactoryGirl.create(:user) 

這樣一個獨特的電子郵件地址的新對象將在每次測試之前創建。

+0

嘿,我試過,但不幸的是我仍然得到相同的錯誤。還有其他建議嗎? – mjgold

+1

你有沒有試過重置你的測試數據庫?耙db:測試:準備 – eeeeeean

4

我在下面描述了同樣的錯誤#2。我發現重新啓動spork並重新運行rake db:test:prepare已解決該錯誤。

+0

這一個固定它給我。那些瘋狂的錯誤之一,因爲它不是你看這是問題的代碼。本教程提到幾次需要重新啓動spork,但這不是其中之一。 –

+0

你救了我的日子:-) – bruThaler