https://kotlinlang.org logo
#getting-started
Title
# getting-started
h

huehnerlady

08/17/2020, 11:20 AM
I would like to write a test method to check whether every field of an object is not null. So if I have a data class
Copy code
data class Test(val property1: String?, property2: Int?)
and I would like to check if that property1 and property2 are not null. But I would like this generic for any object, not this specific one. I currently check, if the String of the object does not contain null, BUT this feels a bit hacky. Any idea how I can do that better?
m

Michael de Kaste

08/17/2020, 11:35 AM
Get memberproperties via reflection:
Copy code
Test::class.memberProperties.all{ it.getter.call(yourInstanceOfTest) != null }
1
h

huehnerlady

08/17/2020, 12:05 PM
ah super cool, thanks 🙂
@Michael de Kaste thank your for your tipp, I am currently working out how best to use it. Now I run into the problem of Java’s ‘private transient’ I created a method like this:
Copy code
fun shouldNotContainNullValues(tested: Any?) {
  tested?: return
  tested::class.memberProperties.all{ it.getter.call(tested) != null }
}
the
?
is a leftover from a more complicated version which tests the submembers of a class This works fine for a string, and other things, but when I try to use javas URI class, I get an IllegalCallableAccessException:
shouldNotContainNullValues(<http://java.net|java.net>.URI.create("foo"))
ends up in
Copy code
kotlin.reflect.full.IllegalCallableAccessException: java.lang.IllegalAccessException: class kotlin.reflect.jvm.internal.calls.CallerImpl$FieldGetter cannot access a member of class java.net.URI (in module java.base) with modifiers "private transient"
Any idea what I can do there?
m

Michael de Kaste

08/17/2020, 1:39 PM
you need to set the field accessible before accessing like so:
Copy code
Test::class.memberProperties.onEach { it.isAccessible = true }.all{ it.getter.call(yourInstanceOfTest) != null }
However, you can't just do this for all classes, for instance, if you look at the URI class you'll see fields like decodedPath and decodedQuery, which are all set to null.
if that's what you wanted to test, sure
h

huehnerlady

08/17/2020, 3:16 PM
hmm I didn’t think that far ahead so I guess I cannot go this route, but will try the accessibility check anyways, thanks 🙂
j

James Richardson

08/17/2020, 5:34 PM
Why not remove the ? from the type...
☝️ 1
h

huehnerlady

08/18/2020, 6:22 AM
If I use it recursively the
it.getter.call(yourInstanceOfTest)
returns a nullable so I need to have the whole function nullable unfortunately
puuh this is really difficult. I have exactly the problem @Michael de Kaste said I would that I have some fields in some classes like URI which has fields that are null… So now I would need to find a way to find out which of my classes/subclasses are null. So I have these classes:
Copy code
data class Test(val property1: String?, val property2: SubTest?)

data class SubTest(val property3: URI?, val property4: Int?)
I would like to fail if any of those properties are null, but not if a subfield of URI is null, or other classes that are not part of my API 🤔 but if I do not do it recursively then
TEST("foo", SubTest(null, 5)
would pass even though
property3
is actually null 🤔 Any idea how I can do that? I assume this is the reason why there isn’t any method like this in kotest already 😓
2 Views