Каков ожидаемый синтаксис для проверки сообщений об исключениях в assert_raises / must_raise MiniTest?

86

Каков ожидаемый синтаксис для проверки сообщений об исключениях в MiniTest's assert_raises/ must_raise?

Я пытаюсь заявить примерно следующее, где "Foo"находится ожидаемое сообщение об ошибке:

proc { bar.do_it }.must_raise RuntimeError.new("Foo")
Кфицпатрик
источник
Связанный: stackoverflow.com/q/3454925/1569
Factor Mystic

Ответы:

150

Вы можете использовать assert_raisesутверждение или must_raiseожидание.

it "must raise" do
  assert_raises RuntimeError do 
    bar.do_it
  end
  ->     { bar.do_it }.must_raise RuntimeError
  lambda { bar.do_it }.must_raise RuntimeError
  proc   { bar.do_it }.must_raise RuntimeError
end

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

describe "testing the error object" do
  it "as an assertion" do
    err = assert_raises RuntimeError { bar.do_it }
    assert_match /Foo/, err.message
  end

  it "as an exception" do
    err = ->{ bar.do_it }.must_raise RuntimeError
    err.message.must_match /Foo/
  end
end
удар
источник
Круто, я понял. Однако я все еще не знаю, как сделать утверждение о появившемся сообщении об ошибке.
kfitzpatrick
3
err = -> {bar.do_it} .must_raise Синтаксис RuntimeError у меня не работал, он продолжал вызывать следующее исключение. NoMethodError: неопределенный метод `assert_raises 'для nil: NilClass
thanikkal
2
@thanikkal Убедитесь, что вы используете, Minitest::Specа не используете Minitest::Test. Spec DSL, включая ожидания, доступны только при использовании Minitest::Spec.
blowmage
28

Чтобы заявить исключение:

assert_raises FooError do
  bar.do_it
end

Чтобы подтвердить сообщение об исключении:

Согласно документу API , assert_raisesвозвращает соответствующее исключение, чтобы вы могли проверить сообщение, атрибуты и т. Д.

exception = assert_raises FooError do
  bar.do_it
end
assert_equal('Foo', exception.message)
Цзин Ли
источник
8

Minitest (пока) не предоставляет вам способ проверить фактическое сообщение об исключении. Но вы можете добавить вспомогательный метод, который делает это, и расширить ActiveSupport::TestCaseкласс для использования повсюду в вашем наборе тестов rails, например: вtest_helper.rb

class ActiveSupport::TestCase
  def assert_raises_with_message(exception, msg, &block)
    block.call
  rescue exception => e
    assert_match msg, e.message
  else
    raise "Expected to raise #{exception} w/ message #{msg}, none raised"
  end
end

и используйте его в своих тестах, например:

assert_raises_with_message RuntimeError, 'Foo' do
  code_that_raises_RuntimeError_with_Foo_message
end
Разработчик
источник
2
Верно то, что Minitest не поддерживает проверку сообщения об ошибке, однако этого можно добиться с помощью, must_raiseпотому что он дает вам экземпляр ошибки, чтобы вы могли проверить сообщение самостоятельно.
bithavoc
1
Мне это решение кажется лучше, но я не использовал его must_raiseраньше.
pumazi
Я думаю, что это решение не потерпит неудачу, если не возникнет исключение. Вы просто проверяете возникшее исключение, чтобы оно было правильным. Но если исключение не возникает, утверждение не выполняется => ошибок нет.
Foton
хороший момент @Foton Я изменил ответ, чтобы отразить это ожидание.
Разработчик
0

Чтобы добавить некоторые более свежие разработки, в прошлом были некоторые дискуссии о добавлении assert_raises_with_messageв minitest, но без особого успеха.

В настоящее время существует многообещающий запрос на перенос, ожидающий объединения. Если и когда он будет объединен, мы сможем использовать его, assert_raises_with_messageне определяя его самостоятельно.

Между тем существует удобная маленькая жемчужина под названием minitest-Bonus-assertions, которая определяет именно этот метод, а также несколько других, так что вы можете использовать его прямо из коробки. Дополнительную информацию см. В документации .

Костас Русис
источник