Alvin Dizon
Alvin Dizon

Reputation: 2009

JUnit 5: How do I use multiple extensions in a test written in Kotlin?

I am trying to migrate my tests for a ViewModel from JUnit 4 to JUnit 5, and use MockK in conjunction. In JUnit4, I have made use of rules--namely rules for RxJava2, LiveData, and Coroutines within one test, and it has worked well. Here's how I use them:

class CollectionListViewModelTest {

    @get:Rule
    val mockitoRule: MockitoRule = MockitoJUnit.rule()

    @get:Rule
    val taskExecutorRule = InstantTaskExecutorRule()

    @get:Rule
    val rxSchedulerRule = RxSchedulerRule()

    @ExperimentalCoroutinesApi
    @get:Rule
    val coroutineRule = MainCoroutineRule()

    @Mock
    lateinit var getAllCollectionsUseCase: GetAllCollectionsUseCase

    private lateinit var SUT: CollectionListViewModel

    @Before
    fun setUp() {
        SUT = CollectionListViewModel(getAllCollectionsUseCase)
    }
...
}

In trying to migrate to JUnit5, I learned that Rules are now Extensions, and after searching I have pieced together replacements for the previous rules I used, and having replaced Mockito with MockK, I have tried to replace Rules with Extensions in this manner:


@ExperimentalCoroutinesApi
@Extensions(
    ExtendWith(InstantExecutorExtension::class),
    ExtendWith(MainCoroutineExtension::class),
    ExtendWith(RxSchedulerExtension::class)
)
class CollectionListViewModelTest {

    @MockK
    lateinit var getAllCollectionsUseCase: GetAllCollectionsUseCase

    private lateinit var SUT: CollectionListViewModel

    @Before
    fun setUp() {
        MockKAnnotations.init(this)
        SUT = CollectionListViewModel(getAllCollectionsUseCase)
    }
...

However, I am getting an error saying that the getMainLooper isn't mocked, which is the same error encountered if not using the InstantTaskExecutorRule in JUnit4:

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.

What is the proper way of using multiple Extensions in Junit5?

Upvotes: 4

Views: 2449

Answers (1)

Alvin Dizon
Alvin Dizon

Reputation: 2009

Instead of using @Extension, I should have used @ExtendWith in this manner:

@ExtendWith(value = [InstantExecutorExtension::class, MainCoroutineExtension::class, RxSchedulerExtension::class])

Or in an even shorter manner:

@ExtendWith(InstantExecutorExtension::class, MainCoroutineExtension::class, RxSchedulerExtension::class)

Upvotes: 7

Related Questions