0

When trying to convert code from Java to Kotlin for an Espresso test,

Java code:

onData(allOf(is(instanceOf(String.class)), is("Americano")))
  .perform(click());

Kotlin code:

onData(allOf(`is`(instanceOf(String::class.java)),
    `is`("Americano"))).perform(click())

The 'is' is actually:

public static <T> Matcher<T> is(T value) {
    return Is.is(value);
}

Why does the syntax for it become 'is' in Kotlin?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
lannyf
  • 9,865
  • 12
  • 70
  • 152
  • 4
    Because `is` is a reserved keyword in Kotlin. – marstran Jan 03 '19 at 15:44
  • See e.g. https://stackoverflow.com/questions/40025927/how-to-compile-kotlin-unit-test-code-that-uses-hamcrest-is, https://kotlinlang.org/docs/reference/keyword-reference.html – jonrsharpe Jan 03 '19 at 15:48

2 Answers2

1

is is a reserved keyword in Kotlin. For interoperability with Java and other programming languages that can name fields or method like reserve words in Kotlin we use backticks to escape names. For example in your case method is from Java is escaped with backticks:

onData(allOf(`is`(instanceOf(String::class.java)),
`is`("Americano"))).perform(click())

Another example of escaping using when method of Mockito library:

Mockito.`when`(/*some method is called*/).thenReturn(/*return some result*/)

Documentation regarding Calling Java code from Kotlin:

Some of the Kotlin keywords are valid identifiers in Java: in, object, is, etc. If a Java library uses a Kotlin keyword for a method, you can still call the method escaping it with the backtick (`) character:

foo.`is`(bar)
Sergio
  • 27,326
  • 8
  • 128
  • 149
1

In Kotlin, identifiers that are also hard keywords (but not soft ones) have to be backticked.

If you want to avoid backticks, you can make an utility extension function for that with a different name:

fun <T> Matcher<T>.isA(value: T) = `is`(value)`
hotkey
  • 140,743
  • 39
  • 371
  • 326