Given mocked `Foo` which has `sealed Bar` and give...
# mockk
k
Given mocked
Foo
which has
sealed Bar
and given two different exhaustive
when
statements:
Copy code
fun Bar.baz() : String {
    when (this) {
        Bam -> "bam"
        Pow -> "pow"
    }
}
Copy code
// Bar
val baz: String
    get() = when(this) {
        Bam -> "bam"
        Pow -> "pow"
    }
}
and given the mocked
Foo.Bar
is of type
Bar_1_Proxy
during the test, why does the extension function result in
NoWhenBranchMatchedException
but the getter results in an empty string?
s
This is expected. You can solve this by using
is
keyword instead:
Copy code
fun Bar.baz() : String {
    when (this) {
        is Bam -> "bam"
        is Pow -> "pow"
    }
}
Or even better, don't mockk data classes 🙂
k
Agreed. We decided to use a factory with randomized data in the end. But, are you saying that using
is
will avoid the exception and both will return empty string? Or both will throw the exception?
s
It will prevent the Exception, because
when
uses reference identity, and mockk can't (or does not support yet) inflating such objects. For the getter, I'm not sure, but
this
might reference the actual object and not the mockk proxy object.
It also depends how you mockk'ed it.
k
Can you elaborate on “`when` uses reference identity”? Forgive my ignorance. Am I understanding correctly that the extension will return empty string as soon as we use
is
?
s
in a when statement •
is Bar
is similar to
if (this is Bar)
, it will check the instance has a compatible type •
Bar
is similar to
if (this === Bar)
, it will check for referential equality (pointing to the same object) https://kotlinlang.org/docs/equality.html
gratitude thank you 1
For the empty string part, I'm not able to answer without more context on how your test looks like
k
To me it makes sense that the exception is thrown, whether it checks for compatible type or referential equality, because there’s no way it can know which subtype it should match with. (I haven’t yet tried to confirm what happens with
is
) What’s confusing is why the getter doesn’t throw the exception and just says, “Eh, I’ll return empty string”. 🤔 And I don’t believe that has anything to do with how the test is set up, but maybe I’m misunderstanding the question.
Yeah, even with putting
is
on all the cases, the exception is still thrown. So, maybe I misunderstood the suggestion/explanation.
s
How are the mocks created? Are they relaxed? Are they based on the abstract type?
k
Relaxed, yes.
s
Then this is probably why it returns an empty string
k
Ahh, so relaxed turns the property into empty string rather than calling the getter? đź’ˇ
s
it returns "default" values
if the type was
String?
it would probably have returned
null
instead
gratitude thank you 1