2011-11-29 33 views
1

我是TDD 元編程的新手,請耐心等待!用rspec模擬動態生成的類在ruby元編程中

我有一個Reporter類(包裹Garb紅寶石寶石),當我點擊method_missing時,它將生成一個新的報告類並將其分配給GoogleAnalyticsReport模塊。主要要點如下:

Reporter.rb

def initialize(profile) 
     @profile = profile 
    end 

def method_missing(method, *args) 

     method_name = method.to_s 
     super unless valid_method_name?(method_name) 

     class_name = build_class_name(method_name) 
     klass = existing_report_class(class_name) || build_new_report_class(method_name, class_name) 
     klass.results(@profile) 
    end 

def build_new_report_class(method_name, class_name) 
     klass = GoogleAnalyticsReports.const_set(class_name, Class.new) 
     klass.extend Garb::Model 
     klass.metrics << metrics(method_name) 
     klass.dimensions << dimensions(method_name) 
     return klass 
    end 

類型「輪廓」的記者希望是一個裝束::管理::簡介。

爲了測試我的一些記者就這個類的私有方法(如valid_method_name?或build_class_name),我相信我要嘲笑與rspec的配置文件,因爲它不是一個細節是我感興趣的

但是,調用克拉斯。 結果(@profile) - 正在執行和殺死我,所以我沒有在我的meta部分中擴展Garb :: Model。

這裏是我如何嘲諷,至今斯塔賓...規範實施當然並不重要:

describe GoogleAnalyticsReports::Reporter do 
before do 

@mock_model = mock('Garb::Model') 
@mock_model.stub(:results) # doesn't work! 

@mock_profile = mock('Garb::Management::Profile') 
@mock_profile.stub!(:session) 

@reporter = GoogleAnalyticsReports::Reporter.new(@mock_profile) 

end 

describe 'valid_method_name' do 
it 'should not allow bla' do 
    @reporter.valid_method_name?('bla').should be_false 
end 


end 
end 

有誰知道我怎麼能存根調用結果方法在我新創建的班上?

任何指針將不勝感激!

〜斯圖

回答

2

相反的:

@mock_model = mock('Garb::Model') 
@mock_model.stub(:results) # doesn't work! 

我想你想做的事:

Garb::Model.any_instance.stub(:results) 

這將存根出裝束的任何實例::模型返回結果。你需要這樣做,因爲你實際上並沒有將@mock_model傳遞給任何使用它的類/方法,所以你必須更加通用一些。

+0

我的項目是rails 2.3,所以我不得不把我的班級放到一個新的gem中,以便在升級rspec mocks時釋放自己的web pf依賴項。我仍然有一個問題,儘管...我們試圖存儲Garb :: Model的實例,它實際上是一個Module,而不是一個Class。 Rspec的給我: 故障/錯誤:裝束:: Model.any_instance.stub(:結果) NoMethodError: 未定義的方法'any_instance」的裝束::型號:模塊 任何想法如何嘲笑類的任何實例那擴展一個模塊? 乾杯 – Stu

+0

我認爲你需要rspec 2.6或更高版本才能獲得any_instance支持。就我所知,除了在模塊的eingen類上定義方法(def self.hello_world)之外,就樁模塊而言,這是不可能的。如果你不知道你想存根的那個實例,那麼我認爲你可能會在你的測試中走錯了路線。 –

+0

同意的Derek - 我想我會糾結起來,因爲我的代碼不正確(閱讀:可測試)就夠了。感謝您的回答。 對於任何人閱讀和感興趣,我結束了使用錄像機和fakeweb殘留的Garb需要的東西。在此處查看我的實施:https://github.com/stuliston/garb-reporter/blob/master/spec/garb_reporter_spec.rb – Stu