rspec控制器测试,预期响应为<重定向>,但<200>

tra*_*man 5 rspec ruby-on-rails factory-bot

我正在使用rspec和Factory Girl进行测试.在测试我的posts_controller的POST #create部分时,我在标题中收到错误.

Failures:

  1) PostsController POST #create with valid attributes redirects to the post
     Failure/Error: response.should redirect_to Post.last
       Expected response to be a <redirect>, but was <200>
     # ./spec/controllers/posts_controller_spec.rb:59:in `block (4 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)

这是正在测试的规范的代码.我确信这不是最有效的方法,但确实有效.

  def create

    @post = Post.new(
      :text => post_params[:text],
      :embed => post_params[:embed],
      :user => current_user,
      :title => post_params[:title],
      :tag_list => post_params[:tag_list],
      :cagegory_ids => post_params[:category_ids]
    )


    if @post.save
      redirect_to @post
    else
      render 'new'
    end

  end

...

  private    
    def post_params
      params.require(:post).permit(:title, :text, :embed, :user_id, :tag_list,
                               :category_ids => [])
    end
Run Code Online (Sandbox Code Playgroud)

这是工厂.

FactoryGirl.define do  
  factory :post do
    title { Faker::Lorem.characters(char_count = 20) }
    text { Faker::Lorem.characters(char_count = 150) }
    user
    categories {
      Array(5..10).sample.times.map do
        FactoryGirl.create(:category)
      end
    }
  end
end
Run Code Online (Sandbox Code Playgroud)

和规范的相关部分

  describe "POST #create" do
    context "with valid attributes" do
      it "saves the new post" do
        expect{
                post :create, post: FactoryGirl.create(:post).attributes
              }.to change(Post,:count).by(1)

      end

      it "redirects to the post" do
        post :create, post: FactoryGirl.create(:post).attributes
        response.should redirect_to Post.last
      end        
    end
  end
Run Code Online (Sandbox Code Playgroud)

另一个测试,"保存新帖子",工作正常.我已经尝试了redirect_to行的其他变体,例如"redirect_to(posts_path(assigns [:post]))",它会抛出相同的错误.

有任何想法吗?

tra*_*man 4

好的,我解决了我的问题。它不漂亮,但很有效。

问题出在工厂女孩和协会上,我绝对不是第一个遇到这个问题的人,但其他解决方案都不起作用。

我最终在 :each 之前添加了这个:在 POST #create 部分的顶部...

  describe "POST #create" do
    before :each do
      Post.destroy_all
      @cat = FactoryGirl.create(:category)
      @newpost = FactoryGirl.build(:post)
      @post_params = {category_ids: [@cat.id]}.merge(@newpost.attributes)
    end
...
Run Code Online (Sandbox Code Playgroud)

...将帖子参数放入一个新的哈希中,我稍后可以在这样的代码中调用...

  it "saves the new post" do
    expect{
             post :create, post: @post_params
           }.to change(Post,:count).by(1)
  end

  it "redirects to the post" do
    post :create, post: @post_params
    response.should redirect_to Post.last
  end 
Run Code Online (Sandbox Code Playgroud)

这样就解决了。它给测试增加了一点开销,但它确实有效。几天内我不会将其标记为解决方案,以防其他人提供一些更好、更简单的代码。我绝对欢迎任何更多的想法。