Kotlinの例外処理をテストでカバーする方法!初心者でも安心のやり方解説
生徒
「Kotlinでエラー処理を書いたんですけど、ちゃんと動くかどうか心配です……」
先生
「そういうときは、テストコードを使って確認できますよ。特に例外処理は、テストでしっかり確認するのが大事なんです。」
生徒
「えっ、エラーをテストできるんですか?やってみたいです!」
先生
「もちろんです。今回はKotlinで例外処理をテストでカバーする方法を、初心者にもわかりやすく説明しますね!」
1. Kotlinの例外処理とは?復習しよう
Kotlinにおける例外処理(エラー処理)とは、プログラムの実行中に予想外のトラブルが起きたときでも、処理を安全に続けるための仕組みです。もし例外処理を書いていないと、エラーが発生した瞬間にプログラムが止まってしまいます。
たとえば「0で割る」「存在しないデータを使う」といった操作は、初心者でもうっかり書いてしまいがちです。こうしたときに活躍するのがtry-catch文です。
fun divide(a: Int, b: Int): Int {
return try {
a / b
} catch (e: ArithmeticException) {
0
}
}
この例では、a / bの計算中にエラーが起きる可能性を考えています。もしbが0だった場合、ArithmeticExceptionというエラーが発生しますが、catchブロックがそれを受け止め、代わりに0を返します。
つまり「問題が起きたら別の安全な処理に切り替える」のが例外処理の役割です。プログラムを途中で止めず、安定して動かすための大切な考え方として覚えておきましょう。
2. 例外処理のテストとは?
「例外処理のテスト」とは、エラーが起きそうな操作をわざと実行して、プログラムが途中で止まらずに、想定どおりに動くかを確認するテストです。特に例外は、普段の操作では再現しにくいので、テストで意識してチェックしておくと安心です。
たとえば、0で割ったときにArithmeticExceptionが出るか、または自分で書いたtry-catchがきちんと動いて「安全な値」を返しているか、といった点を確認できます。
初心者向け:テストは「答え合わせ」みたいなもの
「この操作をしたら、こうなるはず」という期待どおりに動くかを、コードで自動チェックするのがテストです。失敗したらすぐ気づけるので、修正もしやすくなります。
KotlinのテストではJUnit(じぇーゆーにっと)や、Kotlin標準のkotlin.testがよく使われます。JUnitは「正しく動くか確認するための道具」で、例外が起きるケースも安全に確認できます。
import kotlin.test.Test
import kotlin.test.assertEquals
class SimpleExceptionTest {
fun safeDivide(a: Int, b: Int): Int {
return try {
a / b
} catch (e: ArithmeticException) {
0
}
}
@Test
fun testSafeDivideByZero() {
val result = safeDivide(10, 0)
assertEquals(0, result)
}
}
この例は「0で割るとエラーになりそうだけど、例外処理のおかげで0が返る」という動きをテストしています。こうして例外が絡む処理も、テストで落ち着いて確認できます。
3. 例外が発生することをテストする書き方
次のコードでは、あえてエラーを起こして、それをassertFailsWithという関数で確認しています。
assertFailsWithは「このエラーが出るはずだよね?」とテストするものです。
import kotlin.test.Test
import kotlin.test.assertFailsWith
class ExceptionTest {
@Test
fun testDivideByZeroThrowsException() {
assertFailsWith<ArithmeticException> {
val result = 10 / 0
}
}
}
このテストでは、10 / 0がArithmeticExceptionを出すことを確認しています。
4. 例外が出ないことをテストする方法
逆に、エラーが出ないことも確認できます。たとえば、正常な計算でエラーが出ないかをチェックできます。
import kotlin.test.Test
import kotlin.test.assertEquals
class SafeDivideTest {
fun safeDivide(a: Int, b: Int): Int {
return try {
a / b
} catch (e: ArithmeticException) {
0
}
}
@Test
fun testSafeDivideWithValidInput() {
val result = safeDivide(10, 2)
assertEquals(5, result)
}
}
このテストでは、10 ÷ 2 = 5になることをチェックして、ちゃんと計算できているかを確認しています。
5. catchブロックの中身をテストしたいとき
次は、catchの中で何をしているかを確認する方法です。例えばログを出したり、別の値を返したりしているか確認したいときです。
簡単な例では、0で割ったときに0を返すようにして、その戻り値をチェックします。
import kotlin.test.Test
import kotlin.test.assertEquals
class DivideTest {
fun safeDivide(a: Int, b: Int): Int {
return try {
a / b
} catch (e: ArithmeticException) {
0
}
}
@Test
fun testSafeDivideByZeroReturnsZero() {
val result = safeDivide(10, 0)
assertEquals(0, result)
}
}
このように、catchブロックで何か処理をしたあとの結果もテストで確認できます。
6. テストの実行で失敗を防ぐポイント
テストで例外処理を正しくカバーするためには、次のようなポイントに気をつけましょう。
- どんなエラーが起こるか事前に知っておく
- エラーの種類(例:
ArithmeticException)を正しく指定する - 期待される動作(値やメッセージ)を明確にする
- catchの中で何をしているかに注目する
これらを意識すれば、テストで例外処理のカバーがしっかりできます。
7. Kotlin初心者でもできる例外処理テストのコツ
初心者にとって、テストを書くこと自体が難しそうに感じるかもしれません。でも、例外処理のテストは、少しずつ書きながら慣れていくのがコツです。
まずはassertFailsWithとassertEqualsの2つを覚えて、エラーが起きるときと起きないときの両方をチェックできるようにしましょう。
慣れてきたら、リストが空のときの処理や、null(ぬる:中身がない状態)に対する処理など、色々なパターンをテストしてみると練習になります。
まとめ
Kotlinの例外処理をテストで確実にカバーするためには、例外が発生するパターンと発生しないパターンの両方を丁寧に確認することが大切です。例外処理はプログラムの安全性を守るための重要な要素であり、正しく動作しなければアプリケーションが途中で停止したり、想定外の動作を引き起こす原因になります。そのため、try-catch文が期待どおりの挙動をしているか、catchブロックで行っている処理が意図した結果を返しているかをテストで確認しておくことは、初心者から経験者まで必ず意識したいポイントです。 テストで例外処理を扱う際には、assertFailsWithを使って指定した例外が実際に発生するかどうかをチェックし、assertEqualsを用いて例外が出ない場合の戻り値や処理結果を確認します。特にKotlinではエラーの種類が重要で、発生する例外の型を正しく指定しないとテストが意図と異なる形で成功してしまうこともあります。そのため、ArithmeticExceptionやNullPointerExceptionなど、状況に応じた例外の種類を明確に把握し、テストケースに反映させることが求められます。 また、catchブロックに記述している処理内容を確認するテストも、例外処理の品質を高めるうえで非常に有効です。意図したログが出力されているか、別の値を返しているか、場合によっては再スローしているかなど、例外発生時の動きはアプリケーション全体の挙動に影響するため、確実に確認しておきたい部分です。例外処理のテストに慣れてくると、複雑なロジックの中でも安全に動作するコードを作れるようになり、エラーに強いアプリケーション開発につながります。 例外処理テストは難しいと思われがちですが、基本的なパターンを押さえて繰り返し書くことで自然に理解が深まります。特に初心者は、失敗を怖がらずにまずは例外を発生させてみるところから始め、どう動くかを確認する過程を楽しむことが大切です。こうした基礎の積み重ねが、実践的なエラー対応や高品質なテストコードの作成へと繋がっていきます。
サンプルプログラム
以下は、例外が発生するケースと発生しないケースの両方をテストし、catchブロックの結果まで確認する流れをひとつにまとめたサンプルです。例外処理の理解だけでなく、テストコード全体の流れを確認する練習としても役立ちます。
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class ErrorHandlingTest {
fun safeOperate(a: Int, b: Int): Int {
return try {
a / b
} catch (e: ArithmeticException) {
-1
}
}
@Test
fun testThrowsExceptionWhenDivideByZero() {
assertFailsWith<ArithmeticException> {
val x = 20 / 0
}
}
@Test
fun testSafeOperateReturnsMinusOne() {
val result = safeOperate(20, 0)
assertEquals(-1, result)
}
@Test
fun testSafeOperateNormalValue() {
val result = safeOperate(20, 5)
assertEquals(4, result)
}
}
このサンプルでは、正常な値での計算、ゼロ除算での例外発生、catch内の戻り値確認という3パターンを網羅しています。例外処理は複雑に見えても、ひとつひとつ確認していくことで確実に理解を深めることができます。
生徒
「例外処理のテストって難しそうだと思っていましたけど、assertFailsWithとassertEqualsを使えば基本はできるってわかりました!」
先生
「うん、その二つを理解しておけば例外が出る場合と出ない場合の両方を確認できますから、とても便利なんですよ。」
生徒
「catchブロックの中身までテストできるっていうのも驚きでした。例外時の動作ってすごく大事なんですね。」
先生
「その通りです。エラーが発生したあとの動きが正しいかどうかで、アプリ全体の信頼性が変わってきますからね。」
生徒
「最初はこわかったけど、例外をわざと起こしてみるのって意外と楽しいですね!どう動くのかがよくわかります。」
先生
「その姿勢はとても良いですよ。動きを確かめながら学ぶと理解が深まりますし、実践でも役に立ちます。」
生徒
「今日学んだことを活かして、他の関数や処理もテストしてみます!」
先生
「ぜひ挑戦してみてください。例外処理もテストも、経験を積むほど自然に書けるようになりますよ。」