Изучаем, как спекулировать ... кажется, что у тебя проблемы - PullRequest
0 голосов
/ 15 сентября 2010

Вот мой код, который я уточняю:

def vote_up
  get_vote
  @vote.value += 1 unless @vote.value == 1
  @vote.save
  respond_to do |format|
    format.js { render :action => "vote", :layout => false }
  end
end

Кажется, довольно просто. Вот что я пытаюсь уточнить:

  it "should vote up" do
    @mock_cat = Factory.create(:category)
    Category.stub(:mock_cat)
    @mock_post = Factory.create(:post)
    Post.stub(:current_post).and_return(@mock_post)

    @vote = Factory(:vote)

    get :vote_up, :id => @vote
    @vote.reload.value.should == 1    
  end

Это возвращает это:

undefined method `to_i' for #<Vote:0x1052a4af8>

Хотя я не могу понять, почему. Если бы я обозначил свой mock_vote как (: голосования), разве он не прошел бы через метод контроллера и не получил бы +1?

Обновление

Вот приватный метод из моего posts_controller.rb

private

def get_vote
  current_post = Post.all.detect{|r| r.id == params[:id].to_i}
  @post = current_post
  @vote = current_post.votes.find_by_user_id(current_user.id)
  unless @vote
    @vote = Vote.create(:user_id => current_user.id, :value => 0)
    current_post.votes << @vote
  end
end

Ответ:

  it "should vote up" do
    @mock_cat = Factory.create(:category)
    Category.stub(:mock_cat)
    @post = Factory(:post)

    get :vote_up, :id => @post.id
    @post.reload.vote_score.should == 1    
  end

Ответы [ 2 ]

2 голосов
/ 15 сентября 2010

Рекомендую перенести логику с контроллера на модель. Модели намного проще в спецификации. Вместо:

def vote_up
  get_vote
  @vote.value += 1 unless @vote.value == 1
  @vote.save
  respond_to do |format|
    format.js { render :action => "vote", :layout => false }
  end
end

Ваш контроллер должен выглядеть так:

def vote_up
  @vote = Vote.vote_up(params[:id])
  respond_to do |format|
    format.js { render :action => "vote", :layout => false }
  end
end

или, если вам действительно нужно get_vote (может быть, вам следует переместить его в before_filter?)

def vote_up
  @vote.vote_up
  respond_to do |format|
    format.js { render :action => "vote", :layout => false }
  end
end

При необходимости. добавить исключения (может быть с rescue_from )

Тогда вам понадобятся спецификации только в модели и некоторая интеграция ( rspec , стейк, огурец)

1 голос
/ 15 сентября 2010

Трудно понять, что именно делают ваши заглушки, потому что вы не опубликовали код для get_vote.Но я думаю, что вы чрезмерно используете заглушки, когда можете просто использовать преимущества уже созданных фабрик.

it "should vote up" do
  # Does your Vote belong to a post or a category or anything? I don't know. 
  # Modify as needed -- Factory(:vote, :post => Factory(:post))
  @vote = Factory(:vote) 

  get :vote_up, :id => @vote
  @vote.reload.value.should == 1
end

Обратите внимание на reload.Ваш контроллер изменяет запись, которую мы уже извлекли из базы данных, поэтому нам нужно перезагрузить ее, чтобы проверить ее новое значение.

...