2012-01-12 12 views
5

Mi chiedo come convalidare la gente del posto passati a rendere modello di controllerCome convalidare i locali di rendere modello in rspec

Controller:

def lelf_panel 
    # ... 
    if some_condition 
    locals_hash = some_very_long_hash_A 
    else 
    locals_hash = some_very_long_hash_B 
    end 
    render :partial => "left_panel", :layout => false, :locals => locals_hash 
end 

Spec attuale:

it 'should render correct template for lelf_panel' do 
    # ... 
    get 'left_panel' 
    response.should render_template('system/_left_panel') 
end 

Ora ho bisogno di finire Rcov per questo controller, quindi ho bisogno di aggiungere/modificare le specifiche per coprire entrambi i risultati di 'some_condition'. e voglio convalidare i locals 'lelf_panel' passati al rendering, come se io convalidi solo il render_template, la pagina parziale resa per entrambi i risultati sia la stessa.

ho controllare la 'render_template' nei documenti RSpec in http://rubydoc.info/gems/rspec-rails/2.8.1/RSpec/Rails/Matchers/RenderTemplate:render_template

solo fornisco e 2 ° params per messaggio, così come posso testare i locali passati a rendere?

risposta

1

per quanto ne so, non c'è modo di esaminare direttamente i locali per un modello nel modo in cui si sta descrivendo.

È possibile modificare locals_hash in @locals_hash e quindi esaminare i risultati tramite assegnazioni (: locals_hash).

Oppure, è possibile utilizzare i selettori sull'HTML risultante e controllare che ci sia del contenuto indicativo - ad esempio, se locals_hash influisce sul titolo della pagina, controllare che il titolo della pagina HTML risultante sia quello che si aspetta.

14

Invece di utilizzare il matcher render_template, è possibile utilizzare un'aspettativa sull'oggetto controller.

it 'should render correct template for lefl_panel' do 
    # ... 
    allow(controller).to receive(:render).with no_args 
    expect(controller).to receive(:render).with({ 
    :partial => 'system/_left_panel', 
    :layout => false, 
    :locals => some_very_long_hash_A 
    }) 
    get 'left_panel' 
end 
+0

Questo ha funzionato per me - ma solo dopo ho messo il comando get DOPO il commento dovrebbe_receive, e ho anche bisogno di aggiungere controller.stub (: render) per evitare un errore - ma non sono sicuro del perché .... – Phantomwhale

+1

Questa è la risposta superiore. La modifica di un'applicazione per soddisfare le esigenze di una libreria di test è un odore di codice. – user94154

+0

@Phantomwhale Ho appena ricevuto lo stesso errore che hai riscontrato. Il problema è che le nostre aspettative non rendono o reindirizzano nulla, quindi il rendering predefinito viene chiamato alla fine dell'azione. Questo andava bene con rspec, ma ora è un'attesa insoddisfatta. –

1

Uguale @ 's risposta con suggerimenti da @ user2490003' ryan-Ahearn s commento - ma tutti mettono in qualcosa di più flessibile e per RSpec 3.

# Safe to set globally, since actions can either render or redirect once or fail anyway 
    before do 
    allow(controller).to receive(:render).and_call_original 
    end 

    describe "get left panel" do 
    before do 
     # other setup 
     get 'left_panel' 
    end 

    it 'should render correct template for lelf_panel' do 
     # Sadly, render_template is primitive (no hash_including, no block with args, etc.) 
     expect(subject).to render_template('system/_left_panel') 
    end 

    it 'should render with correct local value' do 
     expect(controller).to have_received(:render) do |options| 
     expect(options[:locals][:key_from_very_long_hash]).to eq('value_of_key_from_very_long_hash') 
     end 
    end 
    end 
+0

Ho trovato questo più utile, tuttavia, ho dovuto cambiare la firma del blocco, almeno nella mia versione di rail (3.2, non chiedere;) passa il nome del metodo che viene reso. E.g nel mio controller ho "render" index ", locals: {presenter: presenter}" e nella mia specifica ora ho "expect (controller) .to have_received (: render) do | _method, options | '.. il riposo è lo stesso. –

Problemi correlati