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
Rails: Testing named scopes with RSpec
提问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.
第一种方法的问题在于它实际上查询了数据库。这是缓慢且不必要的。如果您不介意,可以安全地使用第一种方法。第二种方法快速而清晰,所以我会推荐它。

