Как заглушить метод на уже заглушенном методе контроллера с RSpec? - PullRequest
0 голосов
/ 25 февраля 2012

Когда пользователь, которого я пытаюсь отписаться, не существует, я выдаю исключение, которое устанавливает сообщение об ошибке flash и перенаправляет пользователя обратно на страницу, на которой он находился.

Весь доступ к драгоценному камню twitter осуществляется классом TwitterManager, который является обычным классом ruby, расширяющим ActiveModel :: Naming для включения mock_model.

Теперь мне очень трудно понять, как это следует проверить. Код ниже работает, но чувствует себя очень неправильно. Единственный способ, которым я мог заглушить метод twitter.unfollow, был с controller.send (: twitter) .stub (: unfollow) .and_raise (Twitter :: Error :: NotFound.new ("", {}))

Я пытался использовать TwitterManager.any_instance.stub (: unfollow), но это, очевидно, не помогло, как я думал.

Как я могу сделать это лучше? Что я совершенно не понял?

Spec

describe TwitterController do

  before(:each) do
    controller.stub(:twitter).and_return(mock_model("TwitterManager", unfollow: true, follow: true))
  end

  it "unfollows a user when given a nickname" do
    @request.env['HTTP_REFERER'] = '/followers'
    post 'unfollow', id: "existing_user"
    response.should redirect_to followers_path
  end

  describe "POST 'unfollow'" do
    it "does not unfollow a user that does not exist" do
      controller.send(:twitter).stub(:unfollow).and_raise(Twitter::Error::NotFound.new("", {}))
      @request.env['HTTP_REFERER'] = '/followers'
      post 'unfollow', id: "non_existing_user"

      flash[:error].should_not be_nil
      flash[:error].should have_content("not found, could not unfollow")
      response.should redirect_to followers_path
    end
  end

Контроллер

def unfollow
    begin
      twitter.unfollow(params[:id])
      respond_to do |format|
        format.html { redirect_to :back, notice: "Stopped following #{params[:id]}" }
      end
    rescue Twitter::Error::NotFound
      redirect_to :back, :flash => { error: "User #{params[:id]} not found, could not unfollow user" }
    end
  end

[больше кода]

 private
  def twitter
    twitter_service ||= TwitterFollower.new(current_user)
  end

Rspec 2.8.0 Рельсы 3.2.0

1 Ответ

1 голос
/ 25 февраля 2012

Вы можете немного почистить его, сохранив макет TwitterManager в качестве переменной экземпляра в блоке before и вставив прямо в этот объект:

describe TwitterController do

  before(:each) do
    @twitter = mock_model("TwitterManager", unfollow: true, follow: true)
    controller.stub(:twitter).and_return(@twitter)
  end

  # ...

  describe "POST 'unfollow'" do
    it "does not unfollow a user that does not exist" do
      @twitter.stub(:unfollow).and_raise(Twitter::Error::NotFound.new("", {}))
      # ...
    end
  end
end

Но я бы не сказал, что вы делаете "очень неправильно": -)

...