0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails】minitest内で例外を発生させる

Posted at

はじめに

minitest内で例外を任意で発生させる方法について整理してまとめます。

minitest内で例外を発生する主な方法の比較表

方法 コード例 副作用の有無 特徴
① stub obj.stub(:fail, -> {raise "RuntimeError"}) {...} なし(ブロック内のみ有効) 一時的にメソッドを差し替えられる。元のオブジェクトを汚さない
② 特異メソッド def obj.fail; raise "RuntimeError"; end あり(同じインスタンスを再利用すると残る) 直感的に書ける
③ define_method klass = Class.new {define_method(:fail) {raise "RuntimeError"}} あり(クラスを共有すると残る) 複数メソッドをまとめて定義できる
④ Minitest::Mock mock = Minitest::Mock.new; def mock.fail; raise "RuntimeError"; end; mock.expect(:fail, nil); ... なし(テストごとに新規作成) expectメソッドと組み合わせる。呼び出し回数や引数の検証も可能
⑤ Proc / lambda assert_raises(RuntimeError, &-> {raise "RuntimeError"}) なし 最小限のコードで例外テスト可能

① stub

obj = Object.new
def obj.fail; end

obj.stub(:fail, -> {raise "RuntimeError"}) do
  assert_raises(RuntimeError){obj.fail}
end
  • stubで一時的に例外を仕込む
    • ObjectクラスはRubyの全てのクラスの祖先(BasicObjectを除く)。何の振る舞いも持たない、テスト用のダミーオブジェクトを作成する際に重宝される
  • ブロックの中だけで差し替わるので副作用が残らない

② 特異メソッド

obj = Object.new
def obj.fail
  raise "RuntimeError"
end

assert_raises(RuntimeError){obj.fail}
  • オブジェクトに直接メソッドを定義する
  • 同じインスタンスを使い回すと副作用が残る

③ define_method

klass = Class.new do
  define_method(:fail) do
    raise "RuntimeError"
  end
end

obj = klass.new
assert_raises(RuntimeError) {obj.fail}
  • クラス定義の中でメソッドを定義する
  • 複数メソッドを定義できる
  • クラスを共有する他のテストに影響する可能性がある

④ Minitest::Mock

mock = Minitest::Mock.new

def mock.fail
  raise "RuntimeError"
end

mock.expect(:fail, nil)

assert_raises(RuntimeError) {mock.fail}
mock.verify
  • Minitest::Mockのオブジェクトに特異メソッドを定義して例外を発生させる
  • verifyを呼び出すことでexpectの検証を行う

⑤ Proc/lambdaを呼び出す

raise_proc = -> {raise "RuntimeError"}
assert_raises(RuntimeError, &raise_proc)
  • オブジェクトは作らない
  • メソッドの呼び出しの形にはならない
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?