Как проверить, что недопустимые аргументы вызывают исключение ArgumentError, используя RSpec?

Я пишу RubyGem, который может поднять ArgumentError, если аргументы, предоставленные его единственному методу, являются недопустимыми. Как я могу написать тест для этого с помощью RSpec?

В приведенном ниже примере показан вид реализации, который я имею в виду. Метод bar ожидает один логический аргумент (: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

Ответы

Ответ 1

Я использую нечто похожее на то, что опубликовал 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).

Ответ 2

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

Ответ 3

Если очень важно, чтобы вы выбрали исключение для небулевых значений, я думаю, что было бы более элегантным, чтобы принудить значение к логическому, например, с помощью !!:

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

Таким образом, клиентский код может передавать любое правдивое или ложное значение, но вы все равно можете быть уверены, что значение, с которым вы работаете, является правильным логическим. Вы также можете использовать тернарный оператор (например, baz = options.fetch(:baz, true) ? true : false, если вы считаете, что !! неясно.