如何以功能样式从 Arrow 测试 Either

How to test Either from Arrow in functional style

我想用 Either 测试得到的结果。假设我有一个没有 Either

的简单示例
@Test
fun `test arithmetic`() {
    val simpleResult = 2 + 2
    Assertions.assertEquals(4, simpleResult)
}

现在我已经包装了结果:

@Test
fun `test arithmetic with either`() {
    val result : Either<Nothing, Int> = (2 + 2).right()
    Assertions.assertTrue(result.isRight())
    result.map { Assertions.assertEquals(4, it) }
}

我想它看起来有点难看,因为如果我们得到 Either.Left 而不是 Either.Right,最后的断言将不会被执行 如何以函数式风格正确测试结果?

kotlintest 提供了一个 kotest-assertions-arrow 模块,可用于测试箭头类型。

它基本上公开了 Either 和其他数据类型的匹配器。看看this.

@Test
fun `test arithmetic with either`() {
    val result : Either<Nothing, Int> = (2 + 2).right()
    result.shouldBeRight(4)
}

Either 的实现是两边的数据 类 所以你可以这样做:

check(result == 4.right())

或者可以使用与使用 equals 断言相等的任何其他断言库类似的东西。

您可以创建扩展函数:

fun <L, R> Either<L, R>.assertIsLeft(): L {
    return when (this) {
        is Either.Left -> value
        is Either.Right -> throw AssertionError("Expected Either.Left, but found Either.Right with value $value")
    }
}

fun <L, R> Either<L, R>.assertIsRight(): R {
    return when (this) {
        is Either.Right -> value
        is Either.Left -> throw AssertionError("Expected Either.Right, but found Either.Left with value $value")
    }
}

fun <T: Any> T.assertEqualsTo(expected: T): Boolean {
    return this == expected
}

有了它们,您的测试可能如下所示:

val resultRight : Either<Nothing, Int> = (2 + 2).right()
resultRight
    .assertIsRight()
    .assertEqualsTo(4)

val resultLeft: Either<RuntimeException, Nothing> = RuntimeException("Some exception cause").left()
resultLeft
    .assertIsLeft()