Ruby

例外処理とテスト

原因を読み、想定内の失敗へ対応し、結果を自動で確認しましょう。

01

エラーメッセージを読む

まず例外クラスと説明を読み、自分のファイル名と行番号を探します。

失敗例RUBY
numbers = [10, 0]
puts numbers[0] / numbers[1]
表示例OUTPUT
divided by 0 (ZeroDivisionError)

この例は0で整数を割ったことが原因です。入力値の検証が必要です。

02

想定できる失敗を処理する

数値変換の失敗だけをrescue ArgumentErrorで処理します。

begin-rescueRUBY
begin
  number = Integer("abc")
  puts number * 2
rescue ArgumentError
  puts "整数を入力してください"
ensure
  puts "処理を終了します"
end
実行結果OUTPUT
整数を入力してください
処理を終了します

ensureは成功・失敗にかかわらず実行します。理由なくrescueだけを書くと問題を隠すため、具体的な例外を指定します。

03

不正な値を例外で知らせる

raiseで、メソッドが受け付けられない値を呼び出し側へ知らせます。

割引計算RUBY
def discount(price, percent)
  raise ArgumentError, "価格は0以上です" if price.negative?
  unless (0..100).cover?(percent)
    raise ArgumentError, "割引率は0~100です"
  end

  price * (100 - percent) / 100
end

puts discount(2_000, 20)
実行結果OUTPUT
1600
04

Minitestで自動テストする

標準添付のMinitestなら小さなテストをすぐ始められます。

price_test.rbRUBY
require "minitest/autorun"
require_relative "price"

class PriceTest < Minitest::Test
  def test_二割引
    assert_equal 1_600, discount(2_000, 20)
  end

  def test_範囲外の割引率
    assert_raises(ArgumentError) { discount(2_000, 101) }
  end
end
実行COMMAND
ruby price_test.rb
成功時の要点OUTPUT
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
PRACTICE

ミニ課題:送料計算

5000円以上なら0円、未満なら500円を返し、負の注文金額は例外にするメソッドを作ります。0、4999、5000、負数をテストしてください。