簡體   English   中英

Rails:使用 RSpec 測試命名范圍

[英]Rails: Testing named scopes with RSpec

我是測試 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

或者

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自定義輔助方法

RSpec 的創建者最近發表了一篇博客,他認為驗證是行為,關聯是結構 換句話說,他發現關聯(和范圍)不應該被直接測試。 這些測試將根據您想要的行為進行。

換句話說,目前的觀點是不需要直接測試每個作用域,因為您將通過測試應用程序的行為來覆蓋這些關聯。

David Chelimsky 測試范圍(更新)

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

這會產生更“規范”的輸出(使用 --format 文檔時):

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

請注意此答案的來源:

當時的 RSpec 負責人 David Chelimsky 回答了這個問題,Sam Peacey 的鏈接比實際答案獲得了更多的選票。 由於他正在回復某人並在電子郵件鏈中編輯他們的答案,因此不容易找到和跟蹤答案。 這個答案清理並更新了 RSpec 代碼,我猜,他今天會寫的。

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

第一種方法的問題在於它實際上查詢了數據庫。 這是緩慢且不必要的。 如果您不介意,可以安全地使用第一種方法。 第二種方法快速而清晰,所以我會推薦它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM