New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NullPointerException when mocking value class with any() matcher #445
Comments
Workaround is
usage
where
|
Is official support on the roadmap? |
I'm interested too for this topic, any updates? |
Indeed, value classes are more and more widely used. In my case, I used // the interface I want to mock
interface FcoRepository {
fun getRecord(recordId: RecordId, revision: Revision): FcoRecord
}
// Revision is a value class
@JvmInline
value class Revision(val value: Long = 0)
// My test
private val repository = mock<Repository>() {
on { getRecord(any(), any()) } doAnswer { invocation -> ... }
} The result:
|
I've come up with the following workaround for interface ValueClass<T> {
val value: T
}
@JvmInline
value class UserId(override val value: UUID = randomUUID()) : ValueClass<UUID>
val VALUE_CLASS_DEFAULT_VALUES: Map<Any, Any> = mapOf(
UUID::class to UUID.fromString("00000000-0000-0000-0000-000000000000"),
String::class to ""
)
inline fun <reified T : ValueClass<INNER>, reified INNER> anyValueClass(): T =
ArgumentMatchers.any(T::class.java)
?: T::class.java.getDeclaredMethod("box-impl", INNER::class.java)
.invoke(null, VALUE_CLASS_DEFAULT_VALUES.getValue(INNER::class)) as T
// Usage
verify(someMock).someMethod(anyValueClass()) |
Any workaround for private fields? Like |
Hello @FirstSpectr, using @lmartelli workaround that we changed a bit, we made a function inside a MockitoHelper.kt file for our tests, that might also work for the private fields : @JvmInline
value class UserName(val value: String)
object MockitoHelper {
inline fun <reified T> anyValueClass(): T =
ArgumentMatchers.any(T::class.java)
?: T::class.java.getDeclaredMethod("box-impl", T::class.java.declaredFields.first().type)
.invoke(null, null) as T
}
// Usage
verify(someMock).someMethod(anyValueClass()) The trick here is to use the reflection on the generic type to get its first (and only) field. You might have to change its visibility (again using reflection) with As you can see we didn't use the |
@Archigog @lmartelli I tried to use with Do you have a workaround for that too? It seems that instead of throwing (I've tried to with doThrow(MyException())
.whenever(myMock).myMethod(anyValueClass())
|
Is this ticket included in the roadmap? The issue is still relevant |
Hello, I've tried the @Archigog solution and it was partially fine, on my side it worked properly when adjusted in this way: inline fun <reified T> anyValueClass(): T {
val unboxedClass = T::class.java.declaredFields.first().type
return ArgumentMatchers.any(unboxedClass as Class<T>)
?: T::class.java.getDeclaredMethod("box-impl", unboxedClass)
.invoke(null, null) as T
} |
Hi all. I guess the problem here is that I am trying to mock value class. If I remove the
value
modifier this code works fine. Do you have any plans to add support for value classes? Also, I would be very grateful for workaround recommendations.Thanks!
My dependencies:
Code
Test
The test fails with the following exception
Full stacktrace
The text was updated successfully, but these errors were encountered: