2012-06-16 51 views
2

我必須測試一個類別rails模型,與rspec和工廠女孩隔離。我開始定義一個類(記錄)與像FactoryGirl如下:使用RSpec&FactoryGirl在模型中測試rails類方法的正確方法是什麼?

#spec/factories/category.rb 
FactoryGirl.define do 
    factory :category do |f| 
    f.name "A/B Testing" 
    f.tags_array %w(test a/b) 
    end 
end 

和類別型號規格,如:

# spec/models/category_spec.rb 
require 'spec_helper' 

    describe "Category" do 
    before(:each) do 
     @category = FactoryGirl.create(:category) 
    end 
    it "has a valid factory" do 
     @category.should be_valid 
    end 
    it "is invalid without a name" do 
     @category.name = nil 
     @category.should_not be_valid 
    end 
    it "is invalid without at last one tag" do 
     @category.tags_array = nil 
     @category.should_not be_valid 
    end 
    end 

現在我應該定義&試驗,類別類方法其回報a 競爭對手陣列競爭對手這是一個Struct對象,如下所示:

Object.const_set :Competitor, Struct.new(:html_url, :description, :watchers, :forks) 

那麼這個類方法seff.find_competitors_by_tags應該返回結構的數組(數組:競爭結構對象):

def self.find_competitors_by_tags(tags_array) 
    competitors = [] 
    Extractor.each do |wl| 
     competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks) 
    end 
    return competitors 
    end 

什麼是使用RSpec & FactoryGirl測試這種隔離的最佳途徑?我覺得像下面這樣,但我不能說清楚:

spec/factories/competitor.rb 
FactoryGirl.define do 
    factory :competitor do |f| 
    f.html_url "https://github.com/assaf/vanity" 
    f.description "Experiment Driven Development for Ruby" 
    f.watchers "844" 
    f.forks "146" 
    end 
end 

# spec/models/category_spec.rb 
require 'spec_helper' 

    describe "Category" do 
    ... 
    ... 

    it "returns a list of all competitors for each category" do 
     competitors << FactoryGirl.create(:competitor) 
     competitors << Factory.build(:competitor, html_url: "https://github.com/andrew/split", 
            description: "Rack Based AB testing framework", 
            watchers: "357", 
            forks: "42") 
     @category.find_competitors_by_tags("A/B Testing").should == competitors 
    end 
    end 

它不反正工作,我也不能肯定是否是有意義的:

Failures: 

     1) Category returns a list of all competitors for each category 
     Failure/Error: @competitors << FactoryGirl.create(:competitor) 
     NameError: 
      uninitialized constant Competitor 
     # ./spec/models/category_spec.rb:22:in `block (2 levels) in <top (required)>' 

什麼測試這種方法的正確方法?

+0

您可以將其發佈到http://codereview.stackexchange.com/,在那裏沒有足夠的ruby/rails問題imho –

回答

2

你問你怎麼會在隔離測試:

def self.find_competitors_by_tags(tags_array) 
    competitors = [] 
    Extractor.each do |wl| 
     competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks) 
    end 
    return competitors 
    end 

的主要問題是調用Extractor.each ......你應該在數組中發送到這個方法並逆轉這種依賴性。任何時候你的方法都會自行獲取信息,這使得很難測試。因此,像這樣:

def self.find_competitors_by_tags(extractions, tags_array) 
    extractions.map do |wl| 
    Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks) 
    end 
end 

然後你就可以輕鬆地發送這一點,並對其進行測試:

let(:extractions) {[ stub(:competitor), {html_url: "url", description: "description", watchers: "watchers", forks: "forks"] } 

it "should map the extractions" do 
    competitors = Class.find_competitors_by_tags(extractions, nil) 
    competitors.first.html_url.should eq("url") 
    #continue 
end 

最後一點:tags_array似乎未使用。

+0

感謝有關反轉依賴關係的重要提示,無論如何請考慮類方法的最後一次演變,請參閱在Q. –

+0

更新我的推薦立場 –

+0

@ LucaG.Soave代碼似乎越來越複雜。你應該試着讓它變得更簡單。 –

相關問題