【问题标题】:rspec controller testing, Expected response to be a <redirect>, but was <200>rspec 控制器测试,预期响应为 <redirect>,但为 <200>
【发布时间】:2014-02-15 19:24:50
【问题描述】:

我正在使用 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])),但它会引发相同的错误。

有什么想法吗?

【问题讨论】:

  • 如果您能发布您正在点击的控制器代码,那就太好了。
  • 是的,我想补充一点。用控制器代码编辑了帖子,但我相信它会更有效。

标签: ruby-on-rails rspec factory-bot


【解决方案1】:

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

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

我最终在 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
...

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

  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 

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 嗯,好像是这样。它拒绝 category_id 是一个未经许可的参数。我已经进行了验证,以确保它已分配类别。有趣的是,测试失败之前的那个并没有出错,它工作正常。代码本身在生产中有效。我认为 .attributes 正在将 post_params 传递给它,但显然不是。
    • 并且,很抱歉一直用这些东西打击你。添加记录器似乎对我没有帮助。它会在运行代码时保存,因此不会报告任何错误,但在测试中它没有显示记录器中的任何内容。
    • 好的,即使在将我的 post_params 更改为允许之后!它仍然无法正常工作。跟踪日志显示它创建的帖子有 category_id => nil。工厂在我所有的模型测试中运行良好,它将毫无问题地验证。我假设在这个测试中我如何调用 FactoryGirl 有一些语法?我不确定。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多