开发者

How to test controller actions with complicated queries?

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 th开发者_如何学Goe 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?


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.


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜