David Kubecka
08/16/2024, 6:18 AMEither
). I'm trying to convert this to the Raise DSL but I'm getting quite a hairy code at places where I eventually need to handle the error. This is especially visible in tests where I often hard-assume the ok result. Currently, I have this:
class MyService {
fun someMethod(): Result<Int, MyError> = Ok(1)
}
fun test() {
val result = MyService().someMethod().get()
// check result
}
With the Raise DSL, I have this:
class MyService {
fun Raise<MyError>.someMethod(): Int = 1
}
fun test() {
val result =
with(MyService()) {
recover({someMethod()}) { error("not expected") }
}
// check result
}
Isn't there a better way?
(Note that the two ways are not exactly equivalent since in the first case the type of result
is Int?
whereas in the second it's Int
. This is not so important in tests, however.)Emil Kantis
08/16/2024, 6:29 AMfun test() {
val result = either { MyService().someMethod() }.shouldBeRight()
}
shouldBeRight()
is a Kotest Arrow assertion which asserts that the result is OK and unpacks it.David Kubecka
08/16/2024, 6:36 AMeither
way looks certainly better.
fun test() {
val result = either {
with(MyService()) { someMethod() }
}.getOrNull()
}
David Kubecka
08/16/2024, 6:38 AMEmil Kantis
08/16/2024, 6:42 AMclass MyService {
fun someMethod(): Either<MyError, Int> = either { 1 }
}
fun test() {
val result = MyService().someMethod().getOrNull()
}
🙂David Kubecka
08/16/2024, 7:25 AMYoussef Shoaib [MOD]
08/16/2024, 7:50 AMnullable { ignoreErrors { } }
is likely along the lines of what you want. I've also used a shouldSucceed { }
function for tests before, or even a parameter injector thingy from JUnit (can't remember the name) that injects an object : Raise<Any?> { override fun raise(r: Any?) = error("Test failed with $r") }
David Kubecka
08/16/2024, 8:31 AMtestRaise
object since nullable { ignoreErrors { } }
silently swallows all errors. I don't see, however, what's the advantage of using the ParameterResolver (probably that JUnit thingy) over simply using a (statically) defined object. In either case, you have to do with(testRaise) { ... }
anyway.Youssef Shoaib [MOD]
08/16/2024, 8:34 AMRaise<Blah>
as a receiver or a context on your test method!
E.g. :
class MyTestClass {
@Test
context(_: Raise<MyError>, _: Raise<MyOtherError>)
fun fooTest() {
// Both available in context!
}
}
That's because receivers and contexts all compile down to parameters!David Kubecka
08/16/2024, 8:38 AM@ExtendWith(TestRaiseParameterResolver.class)
class MyTestClass {
@Test
fun fooTest(testRaise: TestRaise) {
// ...
}
}
With this I couldn't see the advantage of having the static object injected by JUnit.David Kubecka
08/16/2024, 8:47 AMphldavies
08/16/2024, 8:50 AMinline fun <E, R> shouldNotRaise(block: Raise<E>.() -> R): R =
fold(block, { fail("Unexpected raise of $it") }, ::identity)
inline fun <E> shouldRaise(block: Raise<E>.() -> Any?): E =
fold(block, ::identity) { fail("Expected raise, but returned $it") }
phldavies
08/16/2024, 8:52 AMRiccardo Cardin
08/16/2024, 9:45 AM