Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
443 views
in Technique[技术] by (71.8m points)

kotlin - "the expression is unused" when using kotest in intellij

With this kotlin test written with Kotest, IntelliJ shows the warning "The expression is unused" and syntax coloration is not working. Also, when running the tests, the test is not found.

class TalentMatchServiceSpec : StringSpec() {

    init {


        "add 3 to 2 should give 5"
        {
            // Given integers 2 and 3
            val two = 2
            val three = 3

            // When adding both numbers
            val sum = two + three

            // Then the result is 5
            sum shouldBe 5
        }

    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

@Thomas Martin's answer is correct, but you asked why it makes a difference.

The SpringSpec in Kotest relies on some Kotlin DSL features to work. Let's demonstrate by building the same function from scratch.

We would start by using Kotlin's extension functions. This allows us to add functions to classes we don't control.

So,

fun String.test(test: () -> Unit)

So then we can call this test function on any string:

"this is a test".test({ 1 + 2 shouldBe 3 })

Secondly, Kotlin allows any final lambda arg to be brought outside of the parens. So foo(arg, arg2, arg3, lambda) can become foo(arg, arg2, arg3) lambda. This means we can write our test as:

"this is a test".test { 1 + 2 shouldBe 3 } 

Next, we can mark functions as infix and then we do not need to use the dot to invoke them. So our test function becomes:

infix fun String.test(test: () -> Unit)

And our test now looks like:

"this is a test" test { 1 + 2 shouldBe 3 } 

Finally, any function named invoke and marked as an operator function can be invoked without the function name. So operator fun invoke(a: String, b: String) inside a class Foo can be invoked as both the regular Foo.invoke(a,b) or just Foo(a, b).

So putting all this together, our final test function looks like:

operator fun String.invoke(test: () -> Unit)

And our test ends up as:

"this is a test" { 1 + 2 shouldBe 3 }

Or more likely,

"this is a test" { 
  1 + 2 shouldBe 3 
} 

If the braces are moved to the next line, as in your original question, it just looks like a String followed by an unrelated lambda block. Two different expressions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...