为什么这个 Test::Unit 测试不能在 `post:create` 中保留模型?
我有两个模型: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?
为 true,并且 topic.name
具有来自工厂的值。
然而,这篇文章似乎没有通过 post :create, :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
结果相同的测试错误。
I have two models: User
and Topic
. Users can have many topics and topics belong to one user.
In my Topics controller, I'm trying to test the create action for a valid topic:
The Test
# 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
The Factory (Factory Girl)
# 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
The Test Output
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'
In the test, topic.valid?
is true and topic.name
has a value from the factory.
However, the post doesn't seem to make it past post :create, :topic => topic
. It looks like it's never saved in the database since it doesn't even have an id in the test output.
Edit: Even if I bypass the Factory for the new topic, it doesn't work.
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
Results in the same test error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的
post
方法需要参数作为第二个参数,而不是对象。这是因为控制器中的create
操作将使用params
方法来检索这些参数,并在创建新主题的过程中使用它们,使用如下代码 因此,您的
params[:topic]
需要是您要创建的项目的属性,而不是现有的Topic
对象。但是,您可以使用Factory.build :topic
来获取实例化的Topic
对象,然后执行以下操作以使其正常工作:The
post
method here expects parameters as the second argument, not objects. This is because thecreate
action in your controller is going to be using theparams
method to retrieve these parameters and use them in the process of creating a new topic, using code like this:So therefore your
params[:topic]
needs to be the attributes of the project you want to create, not an existingTopic
object. However, you could useFactory.build :topic
to get an instantiatedTopic
object and then do this to make it work:这远远超出了我的能力范围,但我显然必须在
post :create
参数中手动设置该属性。考虑到:topic => ,这似乎非常违反直觉。 topic
就是这样一个 Rails 习惯用法。希望有人能够解释为什么
post :create, :topic => ; topic
不起作用。This is so far beyond me, but I apparently had to manually set the attribute in the
post :create
params. Seems pretty counter-intuitive given that:topic => topic
is such a Rails idiom.Hopefully someone can shed some light on why
post :create, :topic => topic
wouldn't work.