rspec控制器测试,预期响应是<redirect>,但是&lt; 200&gt; </redirect>

时间:2014-02-15 19:24:50

标签: ruby-on-rails rspec 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)>'

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

  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

这是工厂。

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

与规范的相关部分

  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

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

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

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

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

我之前添加了这个:每个都在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
...

...将post params放入一个新的哈希值,我可以稍后在代码中调用这个哈希...

  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 

所以这个问题已经解决了。它为测试增加了一些开销,但它确实有效。我不会将此标记为几天的解决方案,以防其他人遇到更好,更简单的代码。我绝对欢迎任何更多的想法。

答案 1 :(得分:2)

我认为问题出在工厂。很可能post实例没有通过验证和控制器渲染new视图,这不是重定向,而是成功200.在控制器中添加记录器并查看记录是否实际保存。您还可以阅读测试日志tail -f log/test.log