Apa sintaks yang diharapkan untuk memeriksa pesan pengecualian di assert_raises / must_raise MiniTest?

86

Apa sintaks yang diharapkan untuk memeriksa pesan pengecualian di MiniTest's assert_raises/ must_raise?

Saya mencoba membuat pernyataan seperti berikut, di mana "Foo"pesan kesalahan yang diharapkan:

proc { bar.do_it }.must_raise RuntimeError.new("Foo")
kfitzpatrick.dll
sumber
Terkait: stackoverflow.com/q/3454925/1569
Factor Mystic

Jawaban:

150

Anda dapat menggunakan assert_raisespernyataan, atau must_raiseekspektasi.

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

Jika Anda perlu menguji sesuatu pada objek kesalahan, Anda bisa mendapatkannya dari pernyataan atau ekspektasi seperti:

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
semburan
sumber
Keren, saya mengerti. Namun, saya masih bingung bagaimana membuat pernyataan atas pesan kesalahan yang muncul.
kfitzpatrick
3
err = -> {bar.do_it} .must_raise RuntimeError sintaks tidak bekerja untuk saya, Itu terus memunculkan pengecualian berikut. NoMethodError: metode tak terdefinisi `assert_raises 'untuk nil:
NilClass
2
@thanikkal Pastikan Anda menggunakan Minitest::Specdan tidak Minitest::Test. Spec DSL, termasuk ekspektasi, hanya tersedia saat menggunakan Minitest::Spec.
blowmage
28

Untuk menegaskan pengecualian:

assert_raises FooError do
  bar.do_it
end

Untuk menegaskan pesan pengecualian:

Sesuai dengan dokumen API , assert_raiseskembalikan pengecualian yang cocok sehingga Anda dapat memeriksa pesan, atribut, dll.

exception = assert_raises FooError do
  bar.do_it
end
assert_equal('Foo', exception.message)
Jing Li
sumber
8

Minitest tidak memberi Anda cara untuk memeriksa pesan pengecualian yang sebenarnya. Tapi Anda bisa menambahkan metode helper yang melakukannya dan memperluas ActiveSupport::TestCasekelas untuk digunakan di mana pun di rangkaian pengujian rails Anda, misalnya: intest_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

dan gunakan dalam pengujian Anda seperti:

assert_raises_with_message RuntimeError, 'Foo' do
  code_that_raises_RuntimeError_with_Foo_message
end
Pengembang
sumber
2
Benar bahwa Minitest tidak mendukung pemeriksaan pesan kesalahan, namun itu dapat dilakukan dengan menggunakan must_raisekarena ini memberi Anda contoh kesalahan sehingga Anda dapat memeriksa pesan itu sendiri.
bithavoc
1
Solusi ini terasa lebih baik bagi saya, tetapi saya belum pernah menggunakannya must_raisesebelumnya.
pumazi
Saya pikir solusi ini tidak akan gagal jika tidak ada Pengecualian yang dimunculkan. Anda baru saja memeriksa pengecualian yang dimunculkan untuk menjadi yang benar. Tetapi jika tidak ada pengecualian yang dimunculkan, tidak ada pernyataan yang dilakukan => tidak ada kesalahan.
Foton
poin bagus @Foton Saya mengubah jawaban untuk mencerminkan harapan itu.
Pengembang
0

Untuk menambahkan beberapa perkembangan terbaru, ada beberapa diskusi tentang menambah assert_raises_with_messageminitest di masa lalu tanpa banyak keberuntungan.

Saat ini, ada permintaan tarik yang menjanjikan menunggu untuk digabungkan. Jika dan saat digabungkan, kami akan dapat menggunakan assert_raises_with_messagetanpa harus menentukannya sendiri.

Sementara itu, ada permata kecil yang berguna bernama minitest-bonus-assertions yang mendefinisikan dengan tepat metode itu, bersama dengan beberapa lainnya, sehingga Anda dapat menggunakannya di luar kotak. Lihat dokumen untuk informasi lebih lanjut.

Kostas Rousis
sumber