2013-02-18 16 views
14

Ich bin neu in Rails und Rspec und ich bin mit Rspec dieser Controller-Methode zu testen, die Ausnahmebehandlung beinhaltet:Wie Stuff Error Raise mit Rspec in Rails stub?

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 

ich kann nicht herausfinden, wie man richtig die den Pfad testen: nach ungültiger Suche (Wenn ein Fehler empfangen wird) sollte es auf die Homepage umleiten. Ich habe versucht, so etwas wie dieses:

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 

Nach dem Test mit einem Fehler nicht ausgeführt wird: NameError: uninitialized constant Movie::NoDirectorError

Wie zu fälschen einen Fehler in diesem Test erhöhen, so dass es tatsächlich überprüft, ob Umleitung geschieht?

Danke!

UPDATE:

Wie nzifnab erklärt, es könnte nicht Movie::NoDirectorError finden. Ich habe vergessen, diese Ausnahmeklasse zu definieren. So habe ich es zu app/models/movie.rb:

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

Das ist mein Problem gelöst und dieser Test bestanden wird.

Antwort

11

Der Fehler zeigt an, dass nicht bekannt ist, wo die Ausnahmeklasse Movie::NoDirectorError definiert ist. Möglicherweise müssen Sie speziell die Datei require, in der diese Klasse definiert ist oder der Test möglicherweise nicht finden können.

Rails versucht automatisch, alle constant missing Konstanten unter Verwendung eines konventionellen Dateiverzeichnisformats zu lokalisieren. Es sucht nach einer Datei in load_path bei movie/no_director_error und movie basierend auf dem Namen der Konstante. Wenn die Datei nicht gefunden wird oder die Datei die erwartete Konstante nicht definiert, müssen Sie die Datei speziell anfordern.

+0

Sie haben recht, 'Movie :: NoDirectorError' wurde nirgendwo definiert. Ich habe diese Ausnahmeklasse in 'app/models/movie.rb' definiert und mein Test läuft jetzt. Vielen Dank! –

18

Sie sind sehr nah dran. Sie müssen any_instance dort hinzufügen.

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

edit: Ich habe den Beitrag falsch gelesen. Das obige würde bei einer Instanz von Movie funktionieren, aber nicht bei OPs Frage.

+1

Es ist keine Instanzmethode er benutzt, es ist ein Klasse-Methode. Er hat es richtig. – nzifnab

+0

Das Hinzufügen von any_instance funktionierte bei mir nicht, immer noch mit dem gleichen Fehler. –

+0

Doh. Du hast recht. Ich habe Dinge falsch gelesen. Ignorier mich. –

0

In Rails 4.1:

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

verse_selector.select_verses wird nun zurückkehren ein ActiveRecord::RecordNotFound