2013-07-18 12 views
7

Ich benutze:Wie ein Modell mit einer bestimmten ID mit rspec und Fabrik Mädchen erstellen

gem 'rails', '3.2.11' 
gem 'rspec-rails', '2.13.2' 
gem 'webrat', '0.7.3' 
gem 'factory_girl_rails', '4.1.0' 
gem 'spork', '~> 0.9.0.rc' 

Ich mag meine HP testen, wo ich immer einen Link zu einem bestimmten Benutzer, so dass die Seiten Controller für HP enthält:

@user = User.find(7) 

Und die Aussicht HP enthält:

link_to 'See user', @user 

das Problem ist, dass alle Tests fehlschlagen, da Testdatenbank keine u hat ser mit ID 7. Ich habe versucht:

FactoryGirl.define do 
    factory :user do 
    name "Testuser" 
    id "7" 
    end 
end 

... aber das funktioniert nicht. Es besteht immer die Fehlermeldung:

Die Spezifikation ist dies:

describe "GET 'home'" do 

    before(:each) do 
     FactoryGirl.create(:user) 
    end 

    it "should be successful" do 
     get 'home' 
     response.should be_success 
    end 
end 

Ausfall/Fehler: get 'nach Hause' Active :: RecordNotFound: konnte nicht gefunden werden Benutzer mit id = 7

Der HP funktioniert in der Realität gut, nur der Test schlägt fehl. Wie kann ich sicherstellen, dass dieser Test nicht fehlschlägt?

+1

Ich bin mir nicht sicher, ob das funktionieren würde, aber versuchen Sie ID = 7 –

+0

Können Sie den Code für Ihre fehlerhafte Spezifikation bitte hinzufügen? –

+0

Zeigen Sie den Code Ihrer Spezifikation, wenn Sie nützliche Hilfe benötigen. Bisher raten alle. – boulder

Antwort

8

Was spöttisch/stubbing (viel schneller spec, wenn keine Objekte in der Datenbank zu speichern):

let(:user) { FactoryGirl.build(:user) } 
let(:id) { '1' } 

before do 
    user.stub(:id).and_return(id) # just to illustrate, not necessary if stubbing the find class method 
    User.stub(:find).and_return(user) 
end 

it { expect(user.id).to eq(id) } # just to illustrate 
it { expect(response).to be_success } 
it { expect(assigns(:user)).to eq(user) } 

Wenn Sie noch mit dem Benutzer haben Problem nur instanziiert werden, können Sie immer noch die oben beschriebene Technik verwenden, aber ersetzen FactoryGirl.build(:user) von FactoryGirl.create(:user)

1

Sie können die ID eines Benutzers festlegen, indem jedoch so etwas wie

before 
    u = FactoryGirl.create(:user) 
    u.update_attribute(:id, 7) 
end 

tun, das ist ein wenig seltsam ist. Sie können sogar in einen Fall laufen, wo es Benutzer 7 gibt.

Was Sie tun könnten, obwohl, verwenden Rspec's Stubs, um den richtigen Benutzer zu bekommen. Zum Beispiel Sie so etwas wie

let(:user_7) { FactoryGirl.create(:user) } 
before { User.stub(:find).with(7).and_return(user_7) } 
+0

Danke. Das update_attribute hat die Fehlermeldung nicht geändert ... Ich werde versuchen, die Stubs später zu verwenden ... – user929062

8

Basierend auf dem Using Factories Abschnitt der Dokumentation tun könnte, würde ich die id in der Spezifikation selbst mit so etwas wie ein:

@user = FactoryGirl.create(:user, :id => 7) 
+1

Das klingt logisch, aber ich bekomme immer noch die gleiche Fehlermeldung. – user929062

+3

Für diejenigen, die diese Frage über Google finden. Diese Lösung funktioniert jetzt (August 2015) – Benj

2

keine Antwort, sondern ein suspicition. .. Sie sollten die Spezifikation wahrscheinlich nicht so schreiben, wie Sie es tun.

in der Spec so etwas wie:

u=FactoryGirl.create(:user) 
User.where('id=?',u.id).count.should == 1 

auf bestimmte ids Ihre Tests abhängig machen ein Rezept für eine Katastrophe ist.

+0

Ich stimme Ihnen zu. Aber das Problem ist, dass mein HP eine Verbindung zu diesem bestimmten Benutzer hat. Also, wenn ich den Test ausführe, ist der Fehler, dass die HP nicht gerendert wird, da es keinen Benutzer mit der ID 7 in der Testdatenbank gibt. Dies ist der einzige Test, den ich habe, der von einer ID abhängt, aber ich sehe keinen anderen Weg, dies zu vermeiden. – user929062

0

In Ihrem Fall bin ich sicher, dass Sie nur überprüfen, dass die Benutzer-ID anstelle einer bestimmten ID verwendet wird.

Wenn ich Tests schreibe, bekomme ich nur die ID aus der Datenbank zurück, die viel zuverlässiger und näher an dem ist, was Sie in Wirklichkeit tun.

Ich würde die Controller-Spezifikation so etwas schreiben.

RSpec.describe MyController, type: :controller do 
    let(:user) { FactoryGirl.create(:user) } 
    before do 
    # login the user here which would resolve which user id is being used 
    sign_in user #assumes you are using warden test helpers 
    get :home 
    end 

    it "allows the user to the page" do 
    assert_response :ok 
    end 
end 

Das sollte gut laden. Wenn Sie überprüfen möchten, ob der Link korrekt ist, sollten Sie dies in einer feature Spezifikation mit etwas wie Capybara tun.