question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

lateinit variable doesn't work with interceptTestCase

See original GitHub issue

I have a problem with init lateinit var property in interceptTestCase method. Here is my example:

class ExampleTest : StringSpec() {
    private lateinit var someString: String

    override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) {
        println("Start Testcase")
        someString = "Hello"
        test()
        println("End Testcase")
    }

    init {
        "Hello should equal to Hello" {
            someString shouldEqual "Hello"
        }
    }
}

And here is out put:

Start Testcase

kotlin.UninitializedPropertyAccessException: lateinit property someString has not been initialized

	at com.locata.myapplication.ExampleTest.access$getSomeString$p(ExampleTest.kt:7)
	at com.locata.myapplication.ExampleTest$1.invoke(ExampleTest.kt:18)
	at com.locata.myapplication.ExampleTest$1.invoke(ExampleTest.kt:7)
	at io.kotlintest.Spec$runTest$callable$1$1.invoke(Spec.kt:124)
	at io.kotlintest.Spec$runTest$callable$1$1.invoke(Spec.kt:15)
	at io.kotlintest.Spec$runTest$initialInterceptor$1$1.invoke(Spec.kt:116)
	at io.kotlintest.Spec$runTest$initialInterceptor$1$1.invoke(Spec.kt:15)
	at com.locata.myapplication.ExampleTest.interceptTestCase(ExampleTest.kt:12)
	at io.kotlintest.Spec$runTest$initialInterceptor$1.invoke(Spec.kt:116)
	at io.kotlintest.Spec$runTest$initialInterceptor$1.invoke(Spec.kt:15)
	at io.kotlintest.Spec$runTest$callable$1.call(Spec.kt:124)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)


Process finished with exit code 255

It’s happen for both 2.0.0 and 2.0.1.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:7
  • Comments:15 (12 by maintainers)

github_iconTop GitHub Comments

6reactions
igorwojdacommented, Jun 26, 2017

Proposed solution works only with some specs.

works with StringSpec

class MyTests : BehaviorSpec() {
    lateinit var profilePresenter: ProfilePresenter
    @Mock lateinit var mockEventBus: EventBus

    override val oneInstancePerTest = false

    override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) {
        MockitoAnnotations.initMocks(this)

        profilePresenter = ProfilePresenter(mockEventBus)

        test() // don't forget to call test()!
    }

    init {
        "Should register event buss" {
            profilePresenter.takeView(mockView)
            verify(mockEventBus).register(profilePresenter)
        }
    }
}

but it fails to work with BehaviorSpec

class MyTests : BehaviorSpec() {
    lateinit var profilePresenter: ProfilePresenter
    @Mock lateinit var mockEventBus: EventBus

    override val oneInstancePerTest = false

    override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) {
        MockitoAnnotations.initMocks(this)

        profilePresenter = ProfilePresenter(mockEventBus)

        test() // don't forget to call test()!
    }

    init {
        Given("ProfilePresenter") {

            When("take view") {
                profilePresenter.takeView(mockView)

                Then("register event bus") {
                    verify(mockEventBus).register(profilePresenter)
                }
            }
        }
    }
}

kotlin.UninitializedPropertyAccessException: lateinit property profilePresenter has not been initialized

I strongly feel that this is really big issue, because it’s SUPER unintuitive. To be honest I don’t get the idea behind and the problem with oneInstancePerTest. Your docs say: oneInstancePerTest - By default a single instance of the test class is created for all the test it contains. This seems fine for me. What is the problem by simply calling interceptTestCase before each test and initialize\reinitialize lateinit property before each test? How this relates to single/multiple instances of test class? Why exactly we need to disable it?

2reactions
tonilopezmrcommented, Dec 12, 2017

Please solve this issue!

[Edit 10 mins later]

With this piece of code you can intercept the () -> Unit block like a middleware and run it before any variable initialization.

infix fun String.test(block: () -> Unit): TestCase = this {
    //before initialization
    block()
    //after ..
  }

The use case is:

"init some variables before this code" test {
        // your test ... 
      }

This is a hotfix for this problem, you can rename the method to any other name…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Kotlintest interceptor and lateinit vars - Stack Overflow
When I step through it with a debugger and set a breakpoint in the interceptTestCase methods I see that it is executed before...
Read more >
[Solved]-Kotlintest interceptor and lateinit vars-kotlin
The problem is that you are accessing your lateinit var s inside init {} block, which is default constructor and it is called...
Read more >
Initializing lazy and lateinit variables in Kotlin - LogRocket Blog
This article will explain how the lateinit modifier and lazy delegation can take care of unused or unnecessary early initializations.
Read more >
Table of Contents - Micronaut Documentation
OpenRewrite works with Micronaut applications written in Java, but OpenRewrite doesn't currently support Kotlin or Groovy. Like any automated tool it does much ......
Read more >
Kotlin Cookbook - NIBM eHub
when statement to be exhaustive even when it doesn't return a value, and ... mark it as lateinit, as in the test case...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found