【问题标题】:Why can't this Test::Unit test preserve the model across `post :create`?为什么这个 Test::Unit 测试不能在 `post :create` 中保留模型?
【发布时间】:2011-05-08 01:42:28
【问题描述】:

我有两个模型:UserTopic。用户可以有多个主题,主题属于一个用户。

在我的主题控制器中,我正在尝试测试有效主题的创建操作:

测试

  # topics_controller.test.rb
  def test_create_valid
    sign_in Factory(:user) # Devise will redirect you to the login page otherwise.
    topic = Factory.build :topic
    post :create, :topic => topic
    assert_redirected_to topic_path(assigns(:topic))
  end

工厂(工厂女孩)

# factories.rb
Factory.define :user do |f|
  f.sequence(:username) { |n| "foo#{n}"}
  f.password "password"
  f.password_confirmation { |u| u.password}
  f.sequence(:email) { |n| "foo#{n}@example.com"}
end

Factory.define :topic do |f|
  f.name "test topic"
  f.association :creator, :factory => :user
end

测试输出

ERROR test_create_valid (0.59s) 
      ActionController::RoutingError: No route matches {:action=>"show", :controller=>"topics", :id=>#<Topic id: nil, name: nil, created_at: nil, updated_at: nil, creator_id: 1>}
      /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.0.7/lib/action_dispatch/routing/route_set.rb:425:in `raise_routing_error'

在测试中,topic.valid? 为真,topic.name 具有出厂值。

但是,该帖子似乎没有超过post :create, :topic =&gt; topic。看起来它从未保存在数据库中,因为它甚至在测试输出中都没有 id。

编辑:即使我为新主题绕过工厂,它也不起作用。

  def test_create_valid
    @user = Factory :user
    sign_in @user
    topic = @user.topics.build(:name => "Valid name.")
    post :create, :topic => topic
    assert_redirected_to topic_path(assigns(:topic))
  end

导致同样的测试错误。

【问题讨论】:

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


    【解决方案1】:

    这里的post 方法需要参数作为第二个参数,而不是对象。这是因为控制器中的 create 操作将使用 params 方法来检索这些参数并在创建新主题的过程中使用它们,使用如下代码:

    Topic.new(params[:topic])
    

    因此,您的params[:topic] 需要是您要创建的项目的属性,而不是现有的Topic 对象。但是,您可以使用 Factory.build :topic 获取实例化的 Topic 对象,然后执行此操作以使其工作:

    post :create, :topic => topic.attributes
    

    【讨论】:

      【解决方案2】:

      这远远超出了我的范围,但我显然不得不手动设置 post :create 参数中的属性。鉴于:topic =&gt; topic 是这样一个 Rails 习惯用法,这似乎很违反直觉。

        def test_create_valid
          sign_in @user
          topic = Factory.build :topic
          post :create, :topic => {:name => topic.name}
          assert_redirected_to topic_path(assigns(:topic))
        end
      

      希望有人能解释为什么post :create, :topic =&gt; topic 不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-05
        相关资源
        最近更新 更多