我有两个模型:User
和Topic
。用户可以拥有许多主题和主题属于一个用户。
在我的主题控制器中,我正在尝试测试有效主题的创建操作:
测试
# 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 => 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
导致相同的测试错误。
答案 0 :(得分:1)
此处post
方法将参数作为第二个参数,而不是对象。这是因为控制器中的create
操作将使用params
方法检索这些参数,并在创建新主题的过程中使用它们,使用如下代码:
Topic.new(params[:topic])
因此,您的params[:topic]
需要是您要创建的项目的属性,而不是现有的Topic
对象。但是,您可以使用Factory.build :topic
来获取实例化的Topic
对象,然后执行此操作以使其工作:
post :create, :topic => topic.attributes
答案 1 :(得分:0)
这远远超出我的范围,但我显然必须在post :create
参数中手动设置属性。鉴于:topic => 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 => topic
不起作用。