Ruby-on-rails Rails:使用 RSpec 测试命名范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6485379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:28:02  来源:igfitidea点击:

Rails: Testing named scopes with RSpec

ruby-on-railsrubytestingrspec

提问by andrykonchin

I am new to testing Rails web applications and RSpec. I work with legacy code and need to add tests. So what is the best way to test finders and named scopes with RSpec?

我是测试 Rails Web 应用程序和 RSpec 的新手。我使用遗留代码并需要添加测试。那么使用 RSpec 测试查找器和命名范围的最佳方法是什么?

I find in Google a few approaches but they are not ideal. For example:

我在 Google 中找到了一些方法,但它们并不理想。例如:

http://paulsturgess.co.uk/articles/show/93-using-rspec-to-test-a-named_scope-in-ruby-on-rails

http://paulsturgess.co.uk/articles/show/93-using-rspec-to-test-a-named_scope-in​​-ruby-on-rails

it "excludes users that are not active" do
    @user = Factory(:user, :active => false)
    User.active.should_not include(@user)
end

or

或者

http://h1labs.com/notebook/2008/8/21/testing-named-scope-with-rspec

http://h1labs.com/notebook/2008/8/21/testing-named-scope-with-rspec

it "should have a published named scope that returns ..." do
  Post.published.proxy_options.should == {:conditions => {:published => true}}
end

I find best approach (IMHO) in "Rail Test Prescriptions":

我在“铁路测试处方”中找到了最佳方法(恕我直言):

should_match_find_method :active_only { :active == true }

where should_match_find_methodcustom helper method

should_match_find_method自定义助手方法在哪里

采纳答案by Joost Baaij

The creator of RSpec has recently blogged he thinks Validations are behavior, associations are structure. In other words he finds that associations (and scopes) should not nessesarily be tested directly. Tests for these will follow from the behavior you want.

RSpec 的创建者最近发表了一篇博客,他认为验证是行为,关联是结构。换句话说,他发现关联(和范围)不应该被直接测试。这些测试将根据您想要的行为进行。

In other words, current wisdom is that there is no need to test each scope directly, since you will cover these associations by testing the behavior of your application.

换句话说,目前的观点是不需要直接测试每个作用域,因为您将通过测试应用程序的行为来覆盖这些关联。

回答by hakunin

From https://coderwall.com/p/hc8ofa/testing-rails-model-default_scope-with-rspec

来自https://coderwall.com/p/hc8ofa/testing-rails-model-default_scope-with-rspec

  • no database queries
  • no need to represent the query in a structure
  • 没有数据库查询
  • 无需在结构中表示查询

Example:

例子:

class Trip < ActiveRecord::Base
  default_scope { order(departure: :asc) }
  ...
end

RSpec.describe Trip, type: :model do
  it "applies a default scope to collections by departure ascending" do
    expect(Trip.all.to_sql).to eq Trip.all.order(departure: :asc).to_sql
  end
end

回答by notapatch

David Chelimsky testing scopes (updated)

David Chelimsky 测试范围(更新)

David Chelimsky example, (linked by Sam Peacey's comment), modernised.

David Chelimsky 示例(由 Sam Peacey 的评论链接),将.

# app/models/user.rb

class User < ActiveRecord::Base
  scope :admins, -> { where(admin: true) }
end
# spec/models/user_spec.rb

RSpec.describe User, type: :model do
  describe ".admins" do
    it "includes users with admin flag" do
      admin = User.create!(admin: true)
      expect(User.admins).to include(admin)
    end

    it "excludes users without admin flag" do
      non_admin = User.create(admin: false)
      expect(User.admins).not_to include(non_admin)
    end
  end
end

This produces a more 'spec-like' output (when using --format documentation):

这会产生更“规范”的输出(使用 --format 文档时):

User
  .admins
    includes users with admin flag
    excludes users without admin flag

Note about origination of this answer:

请注意此答案的来源:

David Chelimsky, one of RSpec's creators, answered this question and Sam Peacey's link to it has more votes than the actual answer. The answer is not easy to find and follow as he is replying to someone and editing their answer in an email chain. This answer cleans that up and updates the RSpec code as, I guess, he would have written it today.

RSpec 的创建者之一 David Chelimsky 回答了这个问题,Sam Peacey 的链接比实际答案获得的票数更多。由于他正在回复某人并在电子邮件链中编辑他们的答案,因此不容易找到和跟踪答案。这个答案清理并更新了 RSpec 代码,我猜,他今天会写的。

回答by Jan Minárik

The problem with the first approach is that it actually queries the database. It is slow and unnecessary. If you don't mind, you can safely use the first approach. The second approach is fast and clear so I would recommend it.

第一种方法的问题在于它实际上查询了数据库。这是缓慢且不必要的。如果您不介意,可以安全地使用第一种方法。第二种方法快速而清晰,所以我会推荐它。