我正在为Rails应用程序编写控制器测试,用户可以在其中编写关于其他人的评论(但不是自己)。
reviews_controller_spec.rb
describe "PATCH update" do
it "redirects to user_reviews_url" do
@user = FactoryGirl.create :user
sign_in @user
@user1 = FactoryGirl.create :user
@review = FactoryGirl.create :review
post :create, user_id:@user1.id, review:@review
patch :update, {user_id:@user1.id, id:@review.id}, review: {:description => "john.doeexample1.com"}
flash[:notice].should_not be_nil
flash[:notice].should eq("Review was successfully updated.")
response.should redirect_to(user_path(assigns(:review)))
end
end
factories.rb
FactoryGirl.define do
factory :review do
skill
stars "4"
body "limit: 65535"
end
factory :skill do
name "Cooking"
end
factory :experience do
description "abcdfef"
start_date "1989-11-23"
level "4"
skill
end
factory :user do |u|
u.sequence(:first_name) { |n| "Michael#{n}"}
u.last_name "Harlt"
u.sequence(:email) { |n| "michael#{n}@example.com"}
u.password "foobar123"
u.password_confirmation "foobar123"
u.city "Madison"
u.state "WI"
u.zip_code "53726"
u.date_of_birth "23/11/1989"
end
end
reviews_controller.rb
def update
@skills = @user.skills
if @review.update(review_params)
redirect_to @user, notice: 'Review was successfully updated.'
else
render :edit
end
end
review.rb
class Review < ActiveRecord::Base
has_one :reviewer, class_name: 'User', foreign_key: "reviewer_id"
has_one :reviewee, class_name: 'User', foreign_key: "reviewww_id"
belongs_to :skill
validate :user_cannot_write_review_about_themselves, on: :create
validates_presence_of :stars, :body, :reviewer_id, :reviewee_id, :skill_id
def user_cannot_write_review_about_themselves
if reviewer_id == reviewee_id
errors.add(:reviewer, "cannot write a review about yourself")
end
end
end
错误消息
1) ReviewsController PATCH update redirects to user_reviews_url
Failure/Error: @review = FactoryGirl.create :review
ActiveRecord::RecordInvalid:
Validation failed: Reviewer cannot write a review about yourself, Reviewer can't be blank, Reviewee can't be blank
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/validations.rb:79:in `raise_record_invalid'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/validations.rb:43:in `save!'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/attribute_methods/dirty.rb:29:in `save!'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/transactions.rb:291:in `block in save!'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/transactions.rb:347:in `block in with_transaction_returning_status'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/transaction.rb:188:in `within_new_transaction'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/transactions.rb:220:in `transaction'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/transactions.rb:344:in `with_transaction_returning_status'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activerecord-4.2.0/lib/active_record/transactions.rb:291:in `save!'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/configuration.rb:14:in `block in initialize'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/evaluation.rb:15:in `[]'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/evaluation.rb:15:in `create'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:9:in `tap'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:9:in `result'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/factory.rb:42:in `run'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/factory_runner.rb:23:in `block in run'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/activesupport-4.2.0/lib/active_support/notifications.rb:166:in `instrument'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/factory_runner.rb:22:in `run'
# /Users/shachiagarwalla/.rvm/gems/ruby-2.2.0@zapskills/gems/factory_girl-4.5.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
# ./spec/controllers/reviews_controller_spec.rb:11:in `block (3 levels) in <top (required)>'
如果还需要任何其他代码段,请告诉我。
解决方案 审核未正确创建
before do
@user = FactoryGirl.create :user
@user1 = FactoryGirl.create :user
end
describe "PATCH update" do
it "redirects to user_reviews_url" do
sign_in @user1
@review = FactoryGirl.create(:review, reviewee_id: @user.id, reviewer_id:@user1.id )
patch :update, {user_id:@user.id, id:@review.id, review: {:description => "john.doeexample1.com"}}
flash[:notice].should_not be_nil
flash[:notice].should eq("Review was successfully updated.")
response.should redirect_to(@user)
end
end
答案 0 :(得分:1)
错误是因为当您尝试FactoryGirl.create(:review)
时,它会尝试根据Review.rb
中的验证对其进行验证。
但在您的工厂中,您只设置了三个值:skill, stars, body
。
最好(至少我喜欢)让你的基本工厂创建一个有效的评论。但是,这需要您为要创建的每个reviewer
添加reviewee
和Review
。
在你的测试中你可以这样做:
describe "PATCH update" do
before do
@user = FactoryGirl.create :user
@user1 = FactoryGirl.create :user
end
it "redirects to user_reviews_url" do
sign_in @user
post :create, review: FactoryGirl.attributes_for(:review, reviewee: @user1)
patch :update, id:@review.id, review: {:description => "john.doeexample1.com"}
flash[:notice].should_not be_nil
flash[:notice].should eq("Review was successfully updated.")
response.should redirect_to(user_path(assigns(:review)))
end
end
此代码可能有误,我现在假设您在reviewer
- 行动中将current_user
设置为create
。
如果这不起作用,请同时使用create
- 操作更新您的问题。
我还鼓励你尝试在每个it
- 块中保留一个动作,这个动作肯定可以分成两个测试。
:)