测试评论控制器。 Rspec的

时间:2014-07-09 21:29:32

标签: ruby-on-rails ruby testing rspec

我想测试评论控制器,动作创建,但我不知道如何做到这一点。 的 comments_controller

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

的routes.rb

  resources :hotels do
    resources :comments
    get 'list', on: :collection
    post 'comment'
  end

comments_controller_spec.rb

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

factories.rb

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 POST create创建一个有效的新注释   属性        失败/错误:发布:创建,评论:comment_attr        ActionController的:: UrlGenerationError:          没有路线匹配{:comment =&gt; {:body =&gt;&#34;这是一些评论^ _ ^&#34;,:user =&gt;&#34; 5&#34;,:hotel =&gt; ;&#34; 1&#34;} ,: controller =&gt;&#34;评论&#34;,   :动作=&GT;&#34;创建&#34;}        #./spec/controllers/comments_controller_spec.rb:10:in block (4 levels) in <top (required)>' # ./spec/controllers/comments_controller_spec.rb:8:in阻止(3级)&#39;

     

2)CommentsController POST创建重定向到新评论        失败/错误:发布:创建,评论:comment_attr        ActionController的:: UrlGenerationError:          没有路线匹配{:comment =&gt; {:body =&gt;&#34;这是一些评论^ _ ^&#34;,:user =&gt;&#34; 5&#34;,:hotel =&gt; ;&#34; 1&#34;} ,: controller =&gt;&#34;评论&#34;,   :动作=&GT;&#34;创建&#34;}        #./spec/controllers/comments_controller_spec.rb:16:in块中的“块(3级)”

1 个答案:

答案 0 :(得分:1)

我认为您的主要问题是您已发送到已创建对象的操作

post :create, comment: Comment.create(comment_attr)

Rails解析params并获取记录的id并尝试查找member路由。 看起来您想测试是否会从控制器中的params创建一个新的Comment。它是嵌套资源,因此您也应该发送hotel_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行。我从未见过only选项post - 通常用于资源。