2010-05-16 130 views
13

我正在寫一個RubyGem,如果提供給它的單一方法的參數無效,它可以引發一個ArgumentError。我如何使用RSpec爲此編寫測試?如何測試無效參數使用RSpec引發ArgumentError異常?

下面的例子顯示了我想到的那種實現。該bar方法只需要一個boolean變量(:baz),該類型的檢查,以確保它實際上是一個布爾值:

module Foo 
    def self.bar(options = {}) 
    baz = options.fetch(:baz, true) 
    validate_arguments(baz) 
    end 

    private 
    def self.validate_arguments(baz) 
    raise(ArgumentError, ":baz must be a boolean") unless valid_baz?(baz) 
    end 

    def self.valid_baz?(baz) 
    baz.is_a?(TrueClass) || baz.is_a?(FalseClass) 
    end 
end 

回答

28

我使用類似於JHurra發佈的內容:

it "should raise ArgumentError for arguments that are not boolean" do 
    expect{ Foo.validate_arguments(nil) }.to raise_error(ArgumentError) 
end 

不需要別名(rspec的1.3)

+0

謝謝。 RSpec是否自動訪問私有方法?我的'validate_arguments'方法是私有的。 – 2010-05-16 16:02:05

+6

該方法不是私有的,因爲它是一個類方法,private關鍵字只適用於實例方法。創建方法實例方法或使用'private_class_method:mymethodname'來使類方法保持私有狀態。 – Ragmaanir 2010-05-16 19:26:37

+0

我不知道 - 謝謝。 – 2010-05-16 20:17:26

3
it "should raise ArgumentError for arguments that are not boolean" do 
    lambda{ Foo.validate_arguments(something_non_boolean) }.should raise_error(ArgumentError) 
end 
+0

。謝謝,我已經編輯了原始問題,因爲我忘了指出'validate_arguments'和'valid_baz?'方法是私有的,所以我在做'lambda {Foo.bar(:baz =>'a')} 。如果我在測試中將':baz'設置爲布爾值,那麼測試仍然通過 - 任何想法爲什麼? – 2010-05-16 10:58:04

+4

我喜歡'al' ias:在我的'spec_helper.rb'中運行:lambda',這樣我就可以編寫'running {...} .should raise_error'。 – Theo 2010-05-16 10:58:05

+0

@Theo這是一個好主意。 – 2010-05-16 10:58:53

2

除非你拋出一個異常用於非是非常重要的布爾值,我認爲這將是更優雅的值強制爲布爾值,例如用!!

baz = !! options.fetch(:baz, true) 

這樣的客戶端代碼可以通過任何truthy或falsy價值,但你仍然可以肯定的是價值喲你的工作是一個適當的布爾值。如果你覺得!!不清楚你也可以使用三元運算(例如baz = options.fetch(:baz, true) ? true : false

+0

我明白你的觀點,但我的'validate_arguments'方法實際上也驗證了傳遞給方法的其他參數,使用更復雜的驗證邏輯。 – 2010-05-16 16:03:57

+0

足夠公平......但將它用於布爾值,使用代碼來檢查動態語言中的類型是令人討厭的。 – Theo 2010-05-17 11:36:42

相關問題