如何使用复杂的查询测试控制器操作?

发布于 2024-10-31 23:25:15 字数 601 浏览 1 评论 0原文

假设我有以下操作:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

揽清风入怀 2024-11-07 23:25:15

这就是我喜欢做的事情。一般来说,我喜欢将数据库测试集成到我的测试中(尽管有些人不同意,但我个人喜欢它)。我会创建 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.

我们只是彼此的过ke 2024-11-07 23:25:15

因此,根据评论提取模型是最好的做法。我就是这样做的:

post.rb:

class Post
  scope :tagged_as, lambda {|tag_id| where(:tag_id => tag_id)}
end

posts.yml:

one:
  title: Post 1
  tags: one, three

two:
  title: Post 2
  tags: two, three

post_test.rb:

test 'find by tag' do
  posts = Post.tagged_as(tags(:one))
  assert_includes posts, posts(:one)
  refute_includes posts, posts(:two)
end

So, according to the comments extracting to the model is the best thing to do. That's how I did it:

post.rb:

class Post
  scope :tagged_as, lambda {|tag_id| where(:tag_id => tag_id)}
end

posts.yml:

one:
  title: Post 1
  tags: one, three

two:
  title: Post 2
  tags: two, three

post_test.rb:

test 'find by tag' do
  posts = Post.tagged_as(tags(:one))
  assert_includes posts, posts(:one)
  refute_includes posts, posts(:two)
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文