2

new to Kotlin here!

I just switched some Java testing code into Kotlin and a specific case of null codes is bugging me for the moment. I am trying to test (in a Kotlin @Test code segment) whether this java function raises the right InvalidParameterException:

void addEventListener(
            @NonNull DeviceEventListener listener,
            @Nullable CompletionListener completionListener);

So this function is called through Kotlin code (which worked fine before being converted from java to kotlin) like so: Before in Java :

deviceTest.addEventListener(null, testCompletionListener);
waiter.expect(InvalidParameterException.class);

The test worked well without errors.

After the transition to Kotlin, the code becomes unreachable or raises KotlinNullPointerException:

deviceTest!!.addEventListener(null!!, testCompletionListener)
waiter!!.expect(InvalidParameterException::class.java)

I am new to Kotlin and seriously at lost in how to make it work like it did precedently in Java. Any idea?

Thanks for taking the time!

  • Why are you passing a null parameter to a non nullable field? Also, `!!` will throw a null pointer exception if it is called on null. – PeterK Sep 20 '19 at 14:37
  • One precision, I can't change the java code of the void addEventListener, only the way it is called in the testing code. – Samuel Otis Sep 20 '19 at 14:41
  • @PeterK I am passing a null parameter to test and validate whether the right invalidParameterException is raised. The `!!` was automatically put by the java to kotlin converter – Samuel Otis Sep 20 '19 at 14:42
  • Fair enough if you can't change the interface, but that was not my point. Kotlin will stop you from passing null as a parameter to a non null field. – PeterK Sep 20 '19 at 14:43
  • But Java allowed it though in the past and the test ran well, that's where I'm bugging in my introduction to Kotlin – Samuel Otis Sep 20 '19 at 14:45
  • 2
    Yes, but one of the key differences between java and kotlin is that kotlin has nullable and non nullable types, and you can't pass a nullable type when the code expects a non nullable type. It will force you to convert the value to non-nullable. The easiest (and dirtiest) way is by using `!!` which will throw a null pointer if the value is null. If you need to test this specific scenario, perhaps you should keep the class in java. – PeterK Sep 20 '19 at 14:49

1 Answers1

3

First, in your example you use @NonNull, but I assume you meant @NotNull, as this is the correct annotation Kotlin uses.

Second, I'll assume you take the approach of writing tests in Kotlin, but still using those functions in Java code. Otherwise, if your codebase is in Kotlin only, this test is pointless.

Third, if you try to assign null to @NotNull parameter, you should receive IllegalArgumentException, not InvalidParameterException

Finally, you can make use of platform types to simulate this situation:

// This should be a Java class
public class Nulls {
    public static final DeviceEventListener NULL_DEVICE_EVENT_LISTENER = null;
}

// In Kotlin
deviceTest.addEventListener(Nulls.NULL_DEVICE_EVENT_LISTENER, testCompletionListener)

But since Nulls is a Java class anyway, you may as well just keep the entire test as Java, as was suggested in the comments.

Alexey Soshin
  • 16,718
  • 2
  • 31
  • 40