Rails:使用RSpec测试命名范围

时间:2011-06-26 17:04:04

标签: ruby-on-rails ruby testing rspec

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

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

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

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

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

should_match_find_method :active_only { :active == true }

其中should_match_find_method自定义帮助方法

4 个答案:

答案 0 :(得分:32)

RSpec的创建者最近发表了博客,他认为Validations are behavior, associations are structure。换句话说,他发现不应该直接测试关联(和范围)。对这些的测试将遵循您想要的行为。

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

答案 1 :(得分:4)

来自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

答案 2 :(得分:3)

David Chelimsky测试范围(已更新)

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

# 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

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

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

有关此答案的来源的说明:

RSpec的创建者之一大卫·谢利姆斯基(David Chelimsky)回答了这个问题,萨姆·和平(Sam Peacey)的链接获得的票数超过了实际答案。由于他正在答复某人并在电子邮件链中编辑他们的答案,因此很难找到并跟踪答案。这个答案可以清理并更新RSpec代码,因为我想他今天会写。

答案 3 :(得分:0)

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