Rails:使用RSpec测试命名范围

and*_*hin 32 ruby testing rspec ruby-on-rails

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

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

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
Run Code Online (Sandbox Code Playgroud)

要么

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
Run Code Online (Sandbox Code Playgroud)

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

should_match_find_method :active_only { :active == true }
Run Code Online (Sandbox Code Playgroud)

哪里有should_match_find_method自定义助手方法

Joo*_*aij 32

RSpec的创建者最近在博客中认为,验证是行为,协会是结构.换句话说,他发现不应该直接测试关联(和范围).对这些的测试将遵循您想要的行为.

换句话说,目前的智慧是没有必要直接测试每个范围,因为您将通过测试应用程序的行为来涵盖这些关联.

  • 他没有提到那篇文章中的范围,但为什么你把它们与协会混在一起呢?范围可能比关联更复杂,更容易出错,我相信应该进行测试.由于您调用了强大的创建者,[此处](http://groups.google.com/group/rspec/browse_thread/thread/6706c3f2cceef97f),他建议如果范围属于行为范围(如果不是,为什么它在那里?),那么它应该被指定. (39认同)
  • 我并不反对不应该测试范围.他们肯定应该.只是不直接; 范围的测试应该通过测试应用程序的行为来驱动.我认为范围与关联类似,因为两者都可以有复杂的选项,如连接,包含的模型,其中/ group by/having etcetera.无论如何,这对我来说是有意义的. (4认同)

not*_*tch 14

David Chelimsky 测试范围(更新)

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

# app/models/user.rb

class User < ActiveRecord::Base
  scope :admins, -> { where(admin: true) }
end
Run Code Online (Sandbox Code Playgroud)
# 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
Run Code Online (Sandbox Code Playgroud)

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

User
  .admins
    includes users with admin flag
    excludes users without admin flag
Run Code Online (Sandbox Code Playgroud)

请注意此答案的来源:

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


hak*_*nin 5

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

  • 没有数据库查询
  • 无需在结构中表示查询

例子:

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
Run Code Online (Sandbox Code Playgroud)