2016-09-21 75 views
1

所以我對Rspec很陌生,我試圖弄清楚如何編寫一個將對象作爲構造函數參數的類編寫測試,並設置該對象是一個實例變量。然後在其他方法中調用該實例變量的對象方法。使用gem對象作爲實例變量的類的RSpec測試

例子:

class ClassA 
    def initialize(string_object, gem_object) 
    @instance_variable1 = gem_object 
    @string = string_object 
    end 

    def check_validity?(some_arg) 
    unless @instance_variable1.gemObjectMethod1.gemObjectMethod2(some_arg).empty? 
     return true 
    end 
    false 
    end 
    .. 
    .. 
end 

我覺得怎麼寫這個規格很失落。對於一個我不明白什麼指定一個構造函數實際需要。我意識到的是,我不得不找到某種方式來模仿或琢磨我作爲參數獲得的gem_object,但我不知道如何。

在接下來的方法,我已經試過這一點是:

describe '#check_validity?' do 
    context 'gets empty list' do 
    let (:actual) { subject.check_validity?("sample") } 
    before do 
     allow(subject).to receive(@instance_variable1.gemObjectMethod1.gemObjectMethod2).with("sample").and_return([]) 
    end 
    it 'returns false' do 
     expect(actual).to be false 
    end 
    end 
end 

但是這給了我的錯誤與我的構造說,預計2個論點,但被賦予0

任何幫助將非常感激!另外,我無法真正發現任何關於指定構造函數的參數。也許我正在尋找錯誤的地方,或者錯過了一些明顯的東西,因爲這是我第一次使用BDD。

回答

1

在RSpec中,'receive'是接受表示方法名稱的符號的方法。 (它允許您鏈「與」接受的參數預期的list方法。)要解決的,你可以做到這一點前塊:

before do 
    allow(subject.instance_variable_get(:@instance_variable1).gemObjectMethod1).to receive(:gemObjectMethod2).with("sample").and_return([]) 
end 

的是純粹的醜陋,不過,顧名思義東西錯誤。它是。該代碼違反law of demeter相當糟糕,測試正在被吸收。

作爲第一次嘗試清理它,您可能會考慮一種方法來「緩存」調用@ instance_variable1.gemObjectMethod1的結果。假設第一個方法返回一個可枚舉組件。你可以改變你的類包括這樣的事情:

def check_validity(a_string) 
    widgets.gemObjectMethod2(a_string).empty? 
end 

private 

def widgets 
    @widgets ||= @instance_variable1.gemObjectMethod1 
end 

你的類仍然知道有點太多關於寶石的對象,如今卻以這樣的方式打破下來,你可以重構你是怎麼找到小部件 - 也許是一個不同的寶石或你自己的實現。爲了您的測試目的,您可以通過嘲諷小部件來將該決定從測試中分離出來。

let(:gem_widgets) do 
    instance_double(GemObjectMethod1ResultClass, gemObjectMethod2: true) 
end 

before do 
    allow(subject).to receive(:widgets).and_return(gem_widgets) 
    allow(gem_widgets).to receive(:gemObjectMethod2).with("sample"). 
    and_return([]) 
end 

it 'should pass with "sample"' do 
    expect(actual).to eql true 
end 
+0

謝謝,這很有幫助。你有關於如何測試構造函數的建議嗎?我正在考慮在調用new之前測試一個對象不存在,然後它執行並且它具有正確的實例變量。我對如何測試對象是否已經創建了空白。 – marauder7

+0

我經常用類似這樣的類做的是通過屬性讀取器(例如attr_reader:string_object,:ClassA頂部的gem_object)提供實例變量。如果你這樣做,那麼測試任務是非常簡單的 - 在實例化後檢查getter方法的值。 – AndyV

+0

謝謝。我確實有一個問題。通過創建小部件方法,我不需要確切地找出gemObjectMethod1返回的內容,是否違背抽象原則? – marauder7