2013-02-18 17 views
14

Sono nuovo di Rails e Rspec e sto usando Rspec per testare questo metodo di controllo che comprende la gestione delle eccezioni:Come annullare l'errore durante l'uso di Rspec in Rails?

def search_movies_director 
    @current_movie = Movie.find(params[:id]) 
    begin 
    @movies = Movie.find_movies_director(params[:id]) 
    rescue Movie::NoDirectorError 
    flash[:warning] = "#{@current_movie} has no director info" 
    redirect_to movies_path 
    end 
end 

io non riesco a capire come testare correttamente il detto percorso: dopo la ricerca non valida (quando viene ricevuto un errore) dovrebbe reindirizzare alla homepage. Ho provato qualcosa di simile:

describe MoviesController do 
    describe 'Finding Movies With Same Director' do 
    #some other code 

    context 'after invalid search' do 
     it 'should redirect to the homepage' do 
     Movie.stub(:find) 
     Movie.stub(:find_movies_director).and_raise(Movie::NoDirectorError) 
     get :search_movies_director, {:id => '1'} 
     response.should redirect_to movies_path 
     end 
    end 

    end 
end 

Dopo aver eseguito il test fallisce con un errore: NameError: uninitialized constant Movie::NoDirectorError

Come fingere sollevare un errore in questa prova in modo che verifichi effettivamente se reindirizzamento succede?

Grazie!

UPDATE:

Come ha spiegato nzifnab, non poteva individuare Movie::NoDirectorError. Ho dimenticato di definire questa classe di eccezioni. Così ho aggiunto a app/models/movie.rb:

class Movie < ActiveRecord::Base 
    class Movie::NoDirectorError < StandardError ; end 
    #some model methods 
end 

Questo risolto il mio problema e questo test ha esito positivo.

risposta

11

L'errore indica che non sa dove è definita la classe di eccezione Movie::NoDirectorError. Potrebbe essere necessario specificare nello specifico require il file in cui tale classe è definita o il test potrebbe non essere in grado di trovarlo.

Rails tenterà automaticamente di individuare le costanti constant missing utilizzando un formato di directory di file convenzionale. Cerca un file nello load_path allo movie/no_director_error e nello movie in base al nome della costante. Se il file non viene trovato o il file non definisce la costante prevista di quanto necessario per richiedere il file in modo specifico.

+0

Hai ragione, 'Film :: NoDirectorError' non è stato definito da nessuna parte. Ho definito questa classe di eccezioni in 'app/models/movie.rb' e il mio test passa ora. Grazie! –

18

Sei molto vicino. Devi aggiungere any_instance lì.

Movie.any_instance.stub(:find_movies_director).and_raise(Movie::NoDirectorError) 

modifica: ho letto male il post. Quanto sopra funzionerebbe dato un'istanza di Movie, ma non per la domanda di OP.

+1

Non è un metodo di istanza che sta usando, si tratta di un metodo di classe. Lui ha corretto. – nzifnab

+0

L'aggiunta di any_instance non ha funzionato, ottenendo sempre lo stesso errore. –

+0

Doh. Hai ragione. Leggo male le cose. Ignorarmi. –

0

In Rails 4.1:

verse_selector = double("VerseSelector", select_verses: ActiveRecord::RecordNotFound.new("Verses not found"))

verse_selector.select_verses sarà ora restituire un ActiveRecord::RecordNotFound