Unit Test 等で lambda 関数 を使用しているところで呼び出しログと呼び出し回数を記録したいことはたまによくあると思います。
そこで、記録できる便利クラスを書いてみました。
機能
- 呼び出しログの記録
- 回数の記録と検証(指定された回数呼び出されてなかったらエラーになるように。
AwaitableLambda.kt
import java.util.* import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import java.util.concurrent.TimeoutException class AwaitableLambda<T>( count: Int = 1, val Func: (T) -> Unit = {} ) : (T) -> Unit { private val latch = CountDownLatch(count) private val _callStack = Stack<T>() val callStack: List<T> = _callStack fun isComplete(count: Long = 1, unit: TimeUnit = TimeUnit.SECONDS): Boolean { if (!latch.await(count, unit)) { throw TimeoutException() } return true } override fun invoke(p1: T) { Func(p1) latch.countDown() _callStack.push(p1) } }
一応、Unit Test も雑に書いてみた
internal class awaitableLambdaTest { @Test fun 関数が一度呼び出される検証を行う() { val awaitableLambda = AwaitableLambda<String>() awaitableLambda("") assert(awaitableLambda.isComplete()) } @Test(expected = TimeoutException::class) fun 関数が一度も呼び出されないテスト() { val awaitableLambda = AwaitableLambda<String>() awaitableLambda.isComplete() } @Test fun 関数が過剰に呼び出されるテスト() { val awaitableLambda = AwaitableLambda<String>() awaitableLambda("") awaitableLambda("") } @Test fun 初期状態ではコールスタックに何も積まれていないテスト() { val awaitableLambda = AwaitableLambda<String>() Assert.assertEquals(0, awaitableLambda.callStack.count()) } @Test fun コールスタックに1つ積まれるテスト() { val awaitableLambda = AwaitableLambda<String>() awaitableLambda("Hello") Assert.assertEquals("Hello", awaitableLambda.callStack.elementAt(0)) } @Test fun コールスタックに複数個積まれるテスト() { val awaitableLambda = AwaitableLambda<String>() awaitableLambda("Hello") awaitableLambda("Work") Assert.assertEquals("Hello", awaitableLambda.callStack.elementAt(0)) Assert.assertEquals("Work", awaitableLambda.callStack.elementAt(1)) } }