Как забивать ошибки при помощи Rspec в Rails? - программирование
Подтвердить что ты не робот

Как забивать ошибки при помощи Rspec в Rails?

Я новичок в Rails и Rspec, и я использую Rspec для тестирования этого метода контроллера, который включает обработку исключений:

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

Я не могу понять, как правильно проверить указанный путь: после недопустимого поиска (при получении ошибки) он должен перенаправить на главную страницу. Я пробовал что-то вроде этого:

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

После запуска теста сбой происходит с ошибкой: NameError: uninitialized constant Movie::NoDirectorError

Как подделать сообщение об ошибке в этом тесте, чтобы он действительно проверял, происходит ли перенаправление?

Спасибо!

UPDATE:

Как объяснил nzifnab, он не смог найти Movie::NoDirectorError. Я забыл определить этот класс исключений. Поэтому я добавил его в app/models/movie.rb:

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

Это решило мою проблему, и этот тест проходит.

4b9b3361

Ответ 1

Ошибка указывает, что он не знает, где этот класс исключений Movie::NoDirectorError определен. Возможно, вам понадобится конкретный require файл, в котором этот класс определен, или тест, возможно, не сможет его найти.

Rails автоматически попытается найти любые константы constant missing, используя обычный формат каталога файлов. Он будет искать файл в load_path at movie/no_director_error и movie на основе имени константы. Если файл не найден или файл не определяет ожидаемую константу, вам потребуется конкретный файл.

Ответ 2

Ты очень близко. Вам нужно добавить any_instance.

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

edit: Я неправильно прочитал сообщение. Вышеупомянутое будет работать с экземпляром Movie, но не для вопроса OP.

Ответ 3

В Rails 4.1:

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

verse_selector.select_verses теперь возвращает ActiveRecord::RecordNotFound