2013-12-18 64 views
4

我在我的一個類下一個代碼:如何使用RSpec測試記憶?

class Settings < ActiveRecord::Base 
    def self.current 
    @settings ||= Settings.where({ environment: Rails.env }).first_or_create! 
    end 
    # Other methods 
end 

基本行爲:

  1. 它創建於第一次呼叫的新紀錄。
  2. 它隨後的調用返回相同的結果。
  3. 它在每次更新後重置伊娃,並在隨後的調用中返回與當前環境關聯的第一條(和唯一)記錄。

對於這種方法我也試了下:

describe Settings do 
    describe ".current" do 
    it "gets all settings for current environment" do 
     expect(Settings.current).to eq(Settings.where({ environment: 'test' }).first) 
    end 
    end 
end 

我不覺得舒服,由於我其實不是測試記憶化,所以我一直對this question的方法如下,並我已經試過這樣的事情:

describe ".current" do 
    it "gets all settings for current environment" do 
    expect(Settings).to receive(:where).with({ environment: 'test' }).once 
    2.times { Settings.current } 
    end 
end 

但這種測試返回以下錯誤:

NoMethodError: 
    undefined method `first_or_create!' for nil:NilClass 

所以我的問題是,我怎樣才能用RSpec測試這種方法的記憶?

UPDATE:

最後,我的做法如下:

describe Settings do 
    describe ".current" do 
    it "gets all settings for current environment" do 
     expect(described_class.current).to eq(described_class.where(environment: 'test').first) 
    end 
    it "memoizes the settings for current environment in subsequent calls" do 
     expect(described_class).to receive(:where).once.with(environment: 'test').and_call_original 
     2.times { described_class.current } 
    end 
    end 
end 
+1

無需測試記憶 – NARKOZ

+1

爲什麼我不應該測試記憶? – backpackerhh

回答

7

添加.and_call_original到您的郵件的期望:

expect(Settings).to receive(:where).with({ environment: 'test' }).once.and_call_original 
+1

謝謝!它像一個魅力。我不知道'.and_call_original'。 – backpackerhh

+0

您也可以用'.and_return(stub)'''返回一個存根對象。只要你存根東西,第二次調用將返回緩存的結果。 – cassianoleal

0

下面的代碼調用Settings.current兩次並檢查它們是否都等於ea通過其他來檢查值是否已被記憶。我們還將所有其他我們未測試的方法進行分類。

describe ".current" do 
    it "gets all settings for current environment" do 
    relation = double("relation") 
    expect(relation).to receive(:first_or_create!).once 
    expect(Settings).to receive(:where).with({ environment: 'test' }).once.and_return(relation) 
    settings = Settings.current 
    expect(Settings.current).to eq settings 
    end 
end