Reputation: 11744
I am trying to run an Instrumentation
test (androidTest)
using Mockito
in Android with Kotlin
.
'org.mockito:mockito-core:3.3.3'
Kotlin
so I've org.mockito:mockito-inline:3.3.3
to fix the final class issue.Android
, I've org.mockito:mockito-android:3.3.3
also in my dependencies.but am getting below error while compiling the code
More than one file was found with OS independent path 'mockito-extensions/org.mockito.plugins.MockMaker'
Here's a sample test code to reproduce the issue. Run this test as an Instrumentation test. (androidTest)
.
MainActivityTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
class Calculator {
fun add(x: Int, y: Int): Int {
return x + y
}
}
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@Mock
lateinit var calculator: Calculator
@Before
fun before() {
MockitoAnnotations.initMocks(this)
}
@Test
fun test() {
`when`(calculator.add(10, 10)).thenReturn(20)
assertEquals(calculator.add(10, 10), 20)
}
}
app/build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.theapache64.mockitosample"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'org.mockito:mockito-core:3.3.3'
androidTestImplementation 'org.mockito:mockito-android:3.3.3'
androidTestImplementation 'org.mockito:mockito-inline:3.3.3'
}
Isn't it possible to run Android instrumentation test
using Kotlin
with Mockito
?
NOTE: If you think this is a duplicate question, I've searched all over the internet. There are other issues with similar stack-trace, but my case is different.
Any help would be highly appreciated
Upvotes: 4
Views: 3387
Reputation: 2056
I used these dependencies, they worked for me
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.1")
testImplementation("junit:junit:4.13.2")
testImplementation("androidx.test:core:1.4.0")
testImplementation("org.mockito:mockito-android:4.2.0")
testImplementation("org.mockito:mockito-inline:4.2.0")
testImplementation("org.mockito:mockito-core:4.2.0")
Upvotes: 0
Reputation: 1237
I had the same issue and solution for me was this answer https://stackoverflow.com/a/41594789/2286422, - i.e. to use dexmaker library, which has dependency to Mockito.
Remove other Mockito androidTestImplementation
dependencies and only add below one (you can find the latest version here):
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.28.1'
Note that this solution will only work on devices with Android P or above (official documentation).
Then in actual test I'm using Mockito in following way:
@RunWith(MockitoJUnitRunner::class) // use Mockito runner to be able to use @Mock annotations
class MockitoTest {
@Mock
private lateinit var generalPref: GeneralPreferences
@Before
fun setup() {
// make setup
}
@After
@Throws(IOException::class) {
// make cleanup
}
@Test
fun testUser() {
val repo: UserLocalRepository =
UserLocalRepositoryImpl(generalPref) // generalPref is a mock
val user = repo.getUser()
Truth.assertThat(user).isNotNull()
}
}
Upvotes: 4