如何使用复杂的查询测试控制器操作?
假设我有以下操作:
def index
@posts = Post.joins(:tags).where(:tags => {:id => params[:tag_id]})
end
它将 @posts
暴露给视图,该视图将显示带有给定标签的每个帖子。
一切工作正常,但我一直在试图找出测试它的最佳方法。
我真的不喜欢嘲笑,因为如果我将该行更改为:
@posts = Post.where(:tags => {:id => params[:tag_id]}).joins(:tags)
我真的不想访问数据库,因为它会降低测试速度,所以它可能会阻止测试,但我正在考虑将查询提取到模型内部的方法,并在那里测试它是否是唯一的方法。
编辑:是的,我知道在这种情况下我可以使用Tag.find(params[:tag_id])
,但这不是问题所在。我只是不想在查询中引入另一个模型,并使解释变得更加困难,从而偏离真正的问题,即:我们应该在控制器中保留复杂的查询吗?如果是这样,测试它的最佳方法是什么?
Supposing I have the following action:
def index
@posts = Post.joins(:tags).where(:tags => {:id => params[:tag_id]})
end
It exposes @posts
to the view, which will display every post with the given tag.
Everything works fine, but I'm stuck trying to figure out the best way to test it.
I don't really like mocking, since it could brake the test if I changed that line to:
@posts = Post.where(:tags => {:id => params[:tag_id]}).joins(:tags)
I don't really want to hit the database, as it'd reduce the test speed, but I'm considering extracting the query to a method inside the model, and test it there if it's the only way to do it.
EDIT: Yes, I know I could use Tag.find(params[:tag_id])
in this case, but this is not what the question is about. I just didn't want to introduce another model in the query and make it harder to explain deviating the focus from the real problem, which is: Should we keep complex queries in the controller? If so, what's the best way to test it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是我喜欢做的事情。一般来说,我喜欢将数据库测试集成到我的测试中(尽管有些人不同意,但我个人喜欢它)。我会创建 3 个工厂(:post),也许还有一些标签作为虚拟数据,然后我会调用控制器并检查收到的 @posts 是否是我所期望的。
This is what i like to do. Generally, i like to integrate database testing inside my tests( though some would disagree, i personally like it ). I would create like 3 factories(:post) and maybe some tags as dummy data and then i would call on the controller and check whether the received @posts is what i would expect.
因此,根据评论提取模型是最好的做法。我就是这样做的:
post.rb:
posts.yml:
post_test.rb:
So, according to the comments extracting to the model is the best thing to do. That's how I did it:
post.rb:
posts.yml:
post_test.rb: