# OSGi, JUnit 5 and @TestInstance

**URL:** <https://bnd.discourse.group/t/osgi-junit-5-and-testinstance/216>\
**Category:** GENERAL\
**Created:** [February 19, 2022, 10:59pm UTC](https://bnd.discourse.group/t/osgi-junit-5-and-testinstance/216 "2022-02-19T22:59:50Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![chrisr3](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/chrisr3/32/58_2.png) [@chrisr3](https://bnd.discourse.group/u/chrisr3)\
**Post date:** [February 19, 2022, 10:59pm UTC](https://bnd.discourse.group/t/osgi-junit-5-and-testinstance/216/1 "2022-02-19T22:59:50Z")

</div>

Hi,

I haev recently discovered that JUnit 5 allow you to control whether or not it reuses an instance of a test class for all tests, or creates a new instance for each test. However, the `org.osgi:org.osgi.test.junit5` extension artifact doesn’t appear to support `@TestInstance` 😢.

This test class works:

```nohighlight
package com.example.stuff.testing

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.osgi.framework.Bundle
import org.osgi.framework.BundleContext
import org.osgi.service.component.annotations.RequireServiceComponentRuntime
import org.osgi.test.common.annotation.InjectBundleContext
import org.osgi.test.junit5.context.BundleContextExtension

@ExtendWith(value = [BundleContextExtension::class])
@RequireServiceComponentRuntime
class WorkingTest {
    companion object {
        @InjectBundleContext
        lateinit var bundleContext: BundleContext

        private lateinit var testBundle: Bundle

        @Suppress("unused")
        @BeforeAll
        @JvmStatic
        fun setup() {
            testBundle = bundleContext.bundle
        }
    }

    @Test
    fun myTest() {
        assertEquals("testing", testBundle.symbolicName)
    }
}

```

whereas this one does not:

```nohighlight
package com.example.stuff.testing

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
import org.junit.jupiter.api.extension.ExtendWith
import org.osgi.framework.Bundle
import org.osgi.framework.BundleContext
import org.osgi.service.component.annotations.RequireServiceComponentRuntime
import org.osgi.test.common.annotation.InjectBundleContext
import org.osgi.test.junit5.context.BundleContextExtension

@ExtendWith(value = [BundleContextExtension::class])
@RequireServiceComponentRuntime
@TestInstance(PER_CLASS)
class NotWorkingTest {
    @InjectBundleContext
    lateinit var bundleContext: BundleContext

    private lateinit var testBundle: Bundle

    @BeforeAll
    fun setup() {
        testBundle = bundleContext.bundle
    }

    @Test
    fun myTest() {
        assertEquals("testing", testBundle.symbolicName)
    }
}

```

The exception in the error case is:

```auto
# Execution Finished: NotWorkingTest - [engine:bnd-bundle-engine]/[bundle:testing;1.0.0.SNAPSHOT]/[sub-engine:junit-jupiter]/[class:com.example.stuff.testing.NotWorkingTest] - TestExecutionResult [status = FAILED, throwable = kotlin.UninitializedPropertyAccessException: lateinit property bundleContext has not been initialized]
kotlin.UninitializedPropertyAccessException: lateinit property bundleContext has not been initialized
        at com.example.stuff.testing.NotWorkingTest.setup(NotWorkingTest.kt:26)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        ...

```

which suggests that the injection would have happened in the `@BeforeEach` phase rather than the `@BeforeAll` phase.

`@InjectService` gives similar results.

The point of `@TestInstance` is that `@BeforeAll`/`@AfterAll`-scoped items no longer need to be `static`, and I suspect `org.osgi.test.junit5` is not handling this case.

Cheers,  
Chris

---

<div class="post-metadata">

**Author:** ![juergen-albert](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/juergen-albert/32/20_2.png) [@juergen-albert](https://bnd.discourse.group/u/juergen-albert)\
**Post date:** [February 20, 2022, 12:19am UTC](https://bnd.discourse.group/t/osgi-junit-5-and-testinstance/216/2 "2022-02-20T00:19:56Z")

</div>

Without looking deeper into the cause, I’m not sure if this is related to bnd. This forum is a bit of a mixed bag between OSGi and bnd that is maintained by an overlapping heap of people, but I believe this is a case for the OSGi Test Project. → [GitHub - osgi/osgi-test: Testing support for OSGi. Includes JUnit 4 and JUnit 5 support and AssertJ support.](https://github.com/osgi/osgi-test/)

Would you mind opening an issue there?

---

<div class="post-metadata">

**Author:** ![chrisr3](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/chrisr3/32/58_2.png) [@chrisr3](https://bnd.discourse.group/u/chrisr3)\
**Post date:** [February 20, 2022, 1:52pm UTC](https://bnd.discourse.group/t/osgi-junit-5-and-testinstance/216/3 "2022-02-20T13:52:32Z")

</div>

OK, raised as [Issue #462](https://github.com/osgi/osgi-test/issues/462).
