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


86

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

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

proc { bar.do_it }.must_raise RuntimeError.new("Foo")

Ответы:


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, которая определяет именно этот метод, а также несколько других, так что вы можете использовать его прямо из коробки. Дополнительную информацию см. В документации .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.