2016-12-13 2 views
0

Ich habe eine neue Aktion, die einen Kreis angelegt und mit dem aktuellen Elternteil als Administrator:RSpec - Testen Instanzvariablen innerhalb einer Steuerung

def new 
    return redirect_to(root_path) unless parent 
    @circle = Circle.new(administrator: parent) 
end 

ich, dass die Administrator-ID zu testen, ich versuche, richtig eingestellt ist, und habe meine Prüfung als solche ausgeschrieben:

context 'with a parent signed in' do 
    before do 
    sign_in parent 
    allow(controller).to receive(:circle).and_return(circle) 
    allow(Circle).to receive(:new).and_return(circle) 
    end 

    it 'builds a new circle with the current parent as administrator' do 
    get :new 
    expect(@circle.administrator).to equal(parent) 
    end 
end 

Dies wirft natürlich einen Fehler als @circlenil ist. Wie kann ich auf das neue Objekt zugreifen, das noch nicht von meinen Controller-Tests gespeichert wurde? Ich vermute, es ist eine Vielzahl von erlauben/lassen, aber wie ich schon sagte alle meine Recherchen haben bisher nichts ergeben.

Antwort

2

Sie nähern sich dem Problem falsch. Testen Sie das Verhalten des Controllers. Nicht seine Implementierung.

Wenn dies eine Legacy-Anwendung, die Sie assigns den Zugriff auf das @circle Instanzvariable des Controllers verwenden können:

context 'with a parent signed in' do 
    before do 
    sign_in parent 
    end 
    it 'builds a new circle with the current parent as administrator' do 
    get :new 
    expect(assigns(:circle).administrator).to equal(parent) 
    end 
end 

But Rails 5 removes assigns und deren Verwendung gefördert wird nicht in neuen Projekten. Stattdessen würde ich eine Feature-Spezifikation verwenden und testen Sie tatsächlich die Schritte der Schaffung eines Kreises:

require 'rails_helper' 

RSpec.feature 'Circles' do 

    let(:parent) { create(:parent) } 

    context "a guest user" do 
    scenario "can not create circles" do 
     visit new_circle_path 
     expect(page).to have_content 'Please sign in' 
    end 
    end 

    context "when signed in" do 
    background do 
     login_as parent 
    end 

    scenario "can create circles" do 
     visit new_circle_path 
     fill_in 'name', with: 'Test Circle' 
     expect do 
     click_button 'Create circle' 
     end.to change(parent.circles, :count).by(+1) 
     expect(page).to have_content 'Test Circle' 
    end 
    end 
end 
+0

Leider ist rspec-rails derzeit hinter dem Stand der Technik zurück und die Dokumentation spiegelt nicht wirklich die Verschiebung der Testmethodik wider kam mit Rails 5. Controller-Spezifikationen sind jedoch auf dem Weg nach draußen, da sie auf Komponenten angewiesen sind, die in der nahen Zukunft gerissen werden können. – max

+1

Ich dachte, dass ich mich wahrscheinlich zuerst an den Fehler gewagt hätte - es kam mir nicht in den Sinn, die Tests im Modell selbst durchzuführen. Ich habe für jetzt verwendet, die funktioniert, wird jedoch strukturieren, wie Sie in der Zukunft vorgeschlagen haben. Danke für die Hilfe. – Mark

0

können Sie assigns verwenden:

expect(assigns(:circle).administrator).to eq parent 

Beachten Sie jedoch, dass mit Schienen 5, das als veraltet wird. Der Grund dafür ist, dass das Überprüfen der zugewiesenen Instanzvariablen in Controllern zu fragil und implementierungsspezifisch ist.

Die empfohlene Alternative besteht entweder darin, Nebenwirkungen zu testen (z. B. wenn dies tatsächlich in der db beibehalten wird) oder vollständige Funktionstests durchzuführen.

+0

Danke für die Antwort - ich habe die Schienen-Controller-Test gem so nicht gewohnt bin Lesung bis nur auf das, was es kann Angebot jetzt. – Mark

+0

@Mark, 'rails-controller-testing' war früher Teil von rails. In Schienen 5 wurde es (gemäß dem beschriebenen Grund) entfernt. – ndn

+1

Verwenden Sie 'rails-controller-testing' nicht für ein neues Projekt. Stattdessen mit einer zukunftssicheren Teststrategie gehen. https://everydayrails.com/2016/08/29/replace-rspec-controller-tests.html – max

Verwandte Themen