Який очікуваний синтаксис для перевірки повідомлень про винятки в MiniTest's assert_raises / must_raise?


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. Спектр DSL, включаючи очікування, доступний лише під час використання Minitest::Spec.
ударний удар

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клас для використання скрізь у вашому наборі тестів для рейок, наприклад: в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 Я змінив відповідь, щоб відобразити це очікування.
Розробник

0

Щоб додати кілька останніх подій, у минулому було багато обговорень щодо додавання assert_raises_with_messageдо мінімуму без особливої ​​удачі.

В даний час існує перспективний запит на витяг, який очікує на об’єднання. Якщо і коли він буде об’єднаний, ми зможемо використовувати його assert_raises_with_messageбез необхідності визначати це самостійно.

Тим часом, є цей зручний маленький самоцвіт із назвою minitest-bonus-assertions, який точно визначає цей метод, разом з кількома іншими, так що ви можете використовувати його нестандартно. Докладнішу інформацію див. У документації .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.