2010-05-16 100 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

相关问题