ไวยากรณ์ที่คาดไว้สำหรับการตรวจสอบข้อความยกเว้นใน assert_raises / must_raise ของ MiniTest คืออะไร


87

ไวยากรณ์ที่คาดหวังสำหรับการตรวจสอบข้อความข้อยกเว้นใน MiniTest's assert_raises/ must_raiseคืออะไร?

ฉันกำลังพยายามยืนยันสิ่งต่อไปนี้โดยที่"Foo"ข้อความแสดงข้อผิดพลาดที่คาดไว้:

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

ที่เกี่ยวข้อง: stackoverflow.com/q/3454925/1569
Factor Mystic

คำตอบ:


151

คุณสามารถใช้การ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: undefined method `` assert_raises 'สำหรับ nil: NilClass
thanikkal

2
@thanikkal ให้แน่ใจว่าคุณกำลังใช้และไม่ได้Minitest::Spec Minitest::Testข้อมูลจำเพาะ DSL Minitest::Specรวมถึงความคาดหวังที่มีอยู่เฉพาะเมื่อใช้
blowmage

28

เพื่อยืนยันข้อยกเว้น:

assert_raises FooError do
  bar.do_it
end

ในการยืนยันข้อความยกเว้น:

ตามAPI doc , 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

จุดดี @Foton ฉันเปลี่ยนคำตอบเพื่อสะท้อนความคาดหวังนั้น
พัฒนา

0

เพื่อเพิ่มการพัฒนาล่าสุดมีการพูดคุยเกี่ยวกับการเพิ่มassert_raises_with_messageให้น้อยที่สุดในอดีตโดยไม่ต้องมีโชค

ขณะนี้มีคำขอดึงที่มีแนวโน้มรอให้รวมเข้าด้วยกัน ถ้ามันถูกรวมเข้าด้วยกันเมื่อไรเราจะสามารถใช้ได้assert_raises_with_messageโดยไม่ต้องกำหนดเอง

ในขณะเดียวกันก็มีอัญมณีเล็ก ๆ ที่มีประโยชน์นี้ชื่อว่าminitest-bonus-assertionsซึ่งกำหนดวิธีการนั้นอย่างแน่นอนพร้อมกับวิธีอื่น ๆ อีกเล็กน้อยเพื่อให้คุณสามารถใช้งานได้ทันที ดูเอกสารสำหรับข้อมูลเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.