如何为复杂的 Rails 索引编写集成测试(最佳实践) [英] How to write integration test for complicated rails index (best practices)

查看:41
本文介绍了如何为复杂的 Rails 索引编写集成测试(最佳实践)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个列出文章的页面.控制器中的代码曾经是

Let's say I have a page which lists articles. The code in the controller used to be

# articles#index
@articles = Article.paginate(page: params[:page], per_page: 10, order: :title)

我的测试就像

# spec/requests/article_pages_spec
Article.paginate(page: 1, per_page:10, order: :title).each do |a|
  a.should have_selector('h3', text: a.title)
end

好的.现在我的代码改变了很多.索引就像

Ok fine. Now my code changes a bunch. The index is like

@articles = Article.find(:all, conditions: complicated_status_conditions)
  .sort_by { |a| complicated_weighted_rating_stuff }
  .select { |a| complicated_filters }
  .paginate(...)

什么的.那么我的请求规范现在应该是什么样的?我不想只是将应用程序代码复制并粘贴到测试中,但同时,条件和顺序现在相当复杂,因此测试所有预期元素的存在和顺序肯定会失败,除非我模拟索引控制器.

Or something. So what should my request spec now look like? I don't want to just copy and paste the application code into the test, but at the same time, the conditions and ordering are now fairly complex, so testing the existence and order of all the expected elements will definitely fail unless I emulate the index controller.

做到这一点的最佳方法是什么,避免如此具体的测试,复制应用程序代码?将查询重构到某个中心位置,例如模型并在测试中重新使用它?

What's the best way to do this, avoid testing so specifically, copy in the application code? Refactor the query to some central place like a model and re-use it in the tests?

推荐答案

# articles#index
@articles = Article.paginate(page: params[:page], per_page: 10, order: :title)

我们测试这个的方式不是通过再次编写 Article.paginate(page: params[:page], per_page: 10, order: :title)规格规范必须测试您的程序代码的结果,而不是复制您的程序代码本身!

The way we test this is not by writing Article.paginate(page: params[:page], per_page: 10, order: :title) again in the spec. The spec must test the result of your program code, not copying over your program code itself!

长话短说 - 您必须调用 articles#index 控制器,然后检查 @articles 变量.即

Long story short - you must just call articles#index controller, and afterwards just check the @articles variable. i.e.

# We usually call this as a controller spec
# spec/controllers/articles_controller
# But feel free to put it anywhere you want
describe ArticlesController do
  it "should ..." do
    get :index

    # assigns[:articles] will give the @articles variable contents
    assigns[:articles].each do |a|
      response.should have_selector('h3', text: a.title)
    end
  end
end

通过这种方式,您可以直接使用 @articles 变量本身进行测试,而无需进行第二次查询(这既会消耗不必要的时间,也会导致代码复制).

This way, you directly test using the @articles variable itself, without having to do a second query (which both consumes unnecessary time, as well as results in copying over code).

如果您想测试实际查询本身,那么由于您的查询很复杂,您应该编写如下规范:

If you want to test the actual query itself, then since your query is complicated, you should write a spec like the following:

it "should ..." do
  # Create 10 articles in the database
  # out of which only 5 are expected to match the expected output
  article1  = Article.create! ...
  ...
  article10 = Article.create! ...

  get :index

  # Test whether the articles are correctly filtered and ordered
  assigns[:articles].should == [article5, article3, article7, article1, article4]

脚注编辑 2:添加了用于测试实际查询的额外示例

Footnote Edit 2: Added extra example for testing the actual query

这篇关于如何为复杂的 Rails 索引编写集成测试(最佳实践)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆