Apprendre à spec..seem être avoir des problèmes
-
02-10-2019 - |
Question
Voici mon code, je suis détermination des caractéristiques techniques:
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
Il semble assez simple. Voilà ce que je suis en train de ce spec avec:
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
Il est de retour ceci:
undefined method `to_i' for #<Vote:0x1052a4af8>
Je ne peux pas vraiment comprendre pourquoi si. Si je cogné mon mock_vote comme (: vote)?, Ne serait-il exécuter par la méthode du contrôleur et d'obtenir 1 qui lui est attribué
Mise à jour
Voici la méthode privée de mon 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
Réponse:
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
La solution
Il est difficile de suivre exactement ce que vos talons sont en train de faire parce que vous ne publiez pas le code pour get_vote
. Mais je pense que vous êtes trop en utilisant les talons quand vous pourriez être en profitant des usines que vous êtes déjà en créant.
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
Notez la reload
. Votre contrôleur de modification d'un enregistrement que nous avons déjà tiré de la base de données, nous avons donc besoin de le recharger pour vérifier sa nouvelle valeur.
Autres conseils
Je recommande de passer la logique du contrôleur modèle. Les modèles sont beaucoup plus faciles à spec. Au lieu de:
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
Votre contrôleur devrait ressembler à ceci:
def vote_up
@vote = Vote.vote_up(params[:id])
respond_to do |format|
format.js { render :action => "vote", :layout => false }
end
end
ou, si vous avez vraiment besoin get_vote
(peut-être vous devriez le déplacer vers before_filter?)
def vote_up
@vote.vote_up
respond_to do |format|
format.js { render :action => "vote", :layout => false }
end
end
Si nécessaire. ajouter des exceptions (peut être avec rescue_from )
Ensuite, vous aurez besoin des spécifications que dans le modèle, et une certaine intégration ( rspec , steac, concombre)