Ruby on rails 测试控制器。Rspec
我想测试控制器的评论,创建动作,但我不知道怎么做。 评论\u控制器Ruby on rails 测试控制器。Rspec,ruby-on-rails,ruby,testing,rspec,Ruby On Rails,Ruby,Testing,Rspec,我想测试控制器的评论,创建动作,但我不知道怎么做。 评论\u控制器 class CommentsController < ApplicationController def create @hotel = Hotel.find(params[:hotel_id]) @comment = @hotel.comments.new(comment_params) @comment.user_id = current_user.id @comment.save
class CommentsController < ApplicationController
def create
@hotel = Hotel.find(params[:hotel_id])
@comment = @hotel.comments.new(comment_params)
@comment.user_id = current_user.id
@comment.save
redirect_to @hotel
end
private
def comment_params
params.require(:comment).permit(:user_id, :body, :hotel_id)
end
end
评论\u控制器\u规范rb
resources :hotels do
resources :comments
get 'list', on: :collection
post 'comment'
end
require 'rails_helper'
describe CommentsController do
login_user
describe 'POST create' do
it 'create a new comment with valid attributes' do
expect{
comment_attr = attributes_for(:comment)
post :create, comment: comment_attr
}.to change(Comment,:count).by(1)
end
it 'redirects to the new comment' do
comment_attr = attributes_for(:comment)
post :create, comment: comment_attr
expect(response).to redirect_to hotels_path(hotel)
end
end
end
FactoryGirl.define do
factory :user do |user|
user.email { Faker::Internet.email }
user.password 'password'
user.password_confirmation 'password'
end
factory :hotel do |hotel|
hotel.title 'Hotel'
hotel.description 'This is a some description for hotel'
hotel.breakfast true
hotel.price 20500
hotel.address { create(:address) }
hotel.user { create(:user) }
hotel.avatar { fixture_file_upload(Rails.root + 'spec/fixtures/images/example.jpg', "image/jpg") }
end
factory :comment do |comment|
comment.body 'This is a some comment ^_^'
comment.user { create(:user) }
comment.hotel { create(:hotel) }
end
factory :address do |address|
address.country { Faker::Address.country }
address.state { Faker::Address.state }
address.city { Faker::Address.city }
address.street { Faker::Address.street_name }
end
end
工厂。rb
resources :hotels do
resources :comments
get 'list', on: :collection
post 'comment'
end
require 'rails_helper'
describe CommentsController do
login_user
describe 'POST create' do
it 'create a new comment with valid attributes' do
expect{
comment_attr = attributes_for(:comment)
post :create, comment: comment_attr
}.to change(Comment,:count).by(1)
end
it 'redirects to the new comment' do
comment_attr = attributes_for(:comment)
post :create, comment: comment_attr
expect(response).to redirect_to hotels_path(hotel)
end
end
end
FactoryGirl.define do
factory :user do |user|
user.email { Faker::Internet.email }
user.password 'password'
user.password_confirmation 'password'
end
factory :hotel do |hotel|
hotel.title 'Hotel'
hotel.description 'This is a some description for hotel'
hotel.breakfast true
hotel.price 20500
hotel.address { create(:address) }
hotel.user { create(:user) }
hotel.avatar { fixture_file_upload(Rails.root + 'spec/fixtures/images/example.jpg', "image/jpg") }
end
factory :comment do |comment|
comment.body 'This is a some comment ^_^'
comment.user { create(:user) }
comment.hotel { create(:hotel) }
end
factory :address do |address|
address.country { Faker::Address.country }
address.state { Faker::Address.state }
address.city { Faker::Address.city }
address.street { Faker::Address.street_name }
end
end
但我有一个错误:
1) CommentsController后期创建使用有效的
属性
失败/错误:帖子:创建,注释:注释\u属性
ActionController::UrlGenerationError:
没有路由匹配{:comment=>{:body=>“这是一个注释^ ^”,:user=>“5”,:hotel=>“1”},:controller=>“comments”,
:action=>“create”}
#./spec/controllers/comments\u controller\u spec.rb:10:inblock(4级)in'
#./spec/controllers/comments\u controller\u spec.rb:8:in
块(3级)in'
2) CommentsController创建后重定向到新注释
失败/错误:帖子:创建,注释:注释\u属性
ActionController::UrlGenerationError:
没有路由匹配{:comment=>{:body=>“这是一个注释^ ^”,:user=>“5”,:hotel=>“1”},:controller=>“comments”,
:action=>“create”}
#./spec/controllers/comments\u controller\u spec.rb:16:in'block(3层)in'
我认为您的主要问题是,您将已创建的对象发送到操作
post :create, comment: Comment.create(comment_attr)
Rails解析参数并获取记录的id
,并尝试查找成员
路由。
看起来您想测试是否将从控制器中的参数创建新注释。而且它是嵌套资源,所以您也应该发送酒店id
设法发送
it 'creates a new comment with valid attributes' do
comment_attr = attributes_for(:comment)
hotel = Hotel.last || create(:hotel)
expect{
post :create, comment: comment_attr, hotel_id: hotel.id
}.to change(Comment,:count).by(1)
end
另一件让我困惑的事情是线路
post'comment',only::create
。我从来没有见过选项仅用于post
-通常用于资源。谢谢,我做了这个post-create,comment:comment\u attr
,但这并不能解决我的问题。错误是一样的吗?您是否尝试更改路线(我的意思是仅删除post的选项
)?请参阅答案中的更新。您应该发送hotel\u id
,因为您的资源是嵌套的