2017-04-13 67 views
0

我正在構建一個非常基本的測試,以檢查是否在關係中創建一個對象。 Website has_many languages。我有方法add_language接收一個ID數組並添加它們。優雅的方式來測試新的對象創建

這是我的一些測試:

describe '#add_languages' do 
    subject{ build(:website) } 

    it 'return nil if no language is added' do 
     expect(subject.add_languages []).to be_nil 
    end 
    it 'adds one single language' do 
     languages_ids = [Language.last.id] 
     original_count = subject.languages.count 
     subject.add_languages languages_ids 
     expect(subject.languages.count).to eq(original_count + languages_ids.count) 
    end 
    it 'adds multiple languages' do 
     languages_ids = Language.limit(3).pluck :id 
     original_count = subject.languages.count 
     subject.add_languages languages_ids 
     expect(subject.languages.count).to eq(original_count + languages_ids.count) 
    end 
end 

我不喜歡的是

1)代碼被複制 2)我不喜歡使用eq這一點,但不確定如何使用其他匹配器

什麼是編寫這些測試的優雅方法?

+0

你可以在接收數組language_ids的描述中定義一個函數嗎?通過這種方式,您可以通過簡單地調用該函數來重用代碼。我99%確定紅寶石,ROR會讓你做到這一點。 – corvuszero

回答

0

兩種快速方法可以做到這一點:添加一個輔助方法,或添加一個循環。

helper方法

it "adds on single language" do 
    check_creates_languages([Language.last.id]) 
end 

it "Adds multiple languages" do 
    check_creates_languages(...) 
end 

def check_creates_languages(language_ids) 
    original_count = ... # etc 
end 

[1,3].each do |language_count| 
    it "can add #{language_count} language(s)" do 
    original_count = Language.last(language_count).count 
    # etc 
    end 
end 

而且,沒有什麼錯誤使用eq,這就是它的存在了。你還想使用什麼?您也可以使用be

https://github.com/rspec/rspec-expectations

0

只要你可以這樣做:

expect{subject.add_languages languages_ids}.to change{Language.count}.by(1) 

更多或更少(根據你的使用情況)。