Вот мой классный тест:
private const val FAKE_STRING = "APP NAME"
@RunWith(MockitoJUnitRunner::class)
class UnitTestSample {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
`when`(mockContext.getString(R.string.app_name))
.thenReturn(FAKE_STRING)
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getHelloWorldString()
// ...then the result should be the expected one.
assertThat(result, `is`(FAKE_STRING))
}
}
Вот часть моего gradle.build.kt (Kotlin DSL):
plugins {
id("com.android.application")
kotlin("android")
kotlin("kapt")
kotlin("android.extensions")
id("com.onesignal.androidsdk.onesignal-gradle-plugin")
jacoco
maven
}
dependencies {
...
//Test base
testImplementation("junit:junit:4.12")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.0.3")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.0.3")
androidTestImplementation("androidx.test:runner:1.2.0")
androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")
//Unit Tests
testImplementation("org.mockito:mockito-core:3.0.0")
testImplementation("org.mockito:mockito-inline:3.0.0") //support for kotlin final classes
//Android UI Test
androidTestImplementation("org.robolectric:robolectric:3.7.1")
}
Как видите, Android Studio не распознает Mockito. Я уже импортировал org.mockito.junit.MockitoJUnitRunner
Я запускаю этот образец модульного теста под
src/test/java/.../UnitTestSample.kt
Есть ли у вас какие-либо идеи о том, как заставить его работать?
Изменить (решение):
Я, наконец, заставил это работать с некоторой помощью раздела комментариев. Проблема заключалась в вызвано импортом плагина "maven" в разделе плагинов, и я этого не видел, потому что в базовом проекте, который я скачал для преобразования моего Gradle в DSL Kotlin, эти плагины работали. Каким-то образом это приводило к тому, что Mockito был недоступен во время компиляции, как заявил @MartinZeitler. Согласно @second, «среда выполнения Maven не преобразуется в среду выполнения GradleOnly, а вместо этого компилируется».
@dharms Я импортировал его, но он не распознает, но mockito красный при импорте org.mockito.junit.MockitoJUnitRunner
Вы используете JUnit 4 или 5 - кажется, ваш импорт представляет собой смесь обоих? Если его 5, вы можете попробовать вместо этого расширение.
@ Во-вторых, я использую JUnit 5, импорт JUnit 4 был только для проверки нескольких вещей. Когда я устанавливал Jacoco, он попросил меня использовать TestEngine для запуска тестов покрытия, поэтому я импортировал один JUnit 5. Но я думаю, что нет никакой проблемы. Я могу либо удалить его, либо использовать JUnit Vintage (что обеспечивает обратную совместимость с JUnit 4 и 3).
Редактировать: подчистил ответ
Для JUnit5 и mockito используйте следующие зависимости (или новее) и области видимости:
testImplementation("org.junit.jupiter:junit-jupiter-api:5.4.2")
compile("org.junit.jupiter:junit-jupiter-engine:5.4.2")
testImplementation("org.mockito:mockito-core:3.0.0")
testImplementation("org.mockito:mockito-junit-jupiter:3.0.0")
testImplementation("org.mockito:mockito-inline:3.0.0")
В своем тесте используйте расширение вместо Runner (для JUnit 4).
@ExtendWith(MockitoExtension::class)
При работе с зависимостями JUnit 5 5.0.3 я получил следующую ошибку, поэтому рассмотрите возможность обновления до более новой версии (как показано в зависимостях выше).
java.lang.NoSuchMethodError:
org.junit.platform.commons.support.AnnotationSupport.findAnnotation(Ljava/util/Optional;Ljava/lang/Class;)Ljava/util/Optional;
...
Suppressed: java.lang.NullPointerException
at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:214)
Для преобразования maven в gradle я использовал этот сайт https://sagioto.github.io/maven2gradle/
эта ссылка просто повторяет то, что я написал... когда не работает с Android DSL, но по умолчанию используется Java.
@второй я добавил testImplementation ("org.mockito:mockito-junit-jupiter:3.0.0")
и @ExtendWith(MockitoExtension::class)
и удалил зависимость для JUnit 4. Но теперь он говорит мне Unsolved reference: MockitoExtension::class
@во-вторых, я наконец-то понял!!! в моем разделе плагинов я добавил «maven» (я не знаю, почему), и это вызывало ошибку. Я добавлю подробности в конец моего ответа
На самом деле я только что понял, что maven runtime
переводится не в gradle runtimeOnly
, а вместо этого compile
. Так что Martin Zeitler
, возможно, был прав насчет этой части.
Да, у меня было это понимание, потому что все вы и ваши комментарии. Спасибо вам, ребята!
Я очистил свой ответ, нет смысла оставлять там попытки и ошибки;)
Сообщение об ошибке довольно ясное: an annotation argument must be a compile time argument
.
Замените testImplementation
на:
debugImplementation "org.mockito:mockito-android:3.2.4"
debugImplementation "org.mockito:mockito-inline:3.2.4"
@second @RunWith
— аннотация, а MockitoJUnitRunner
— аргумент; по какой-то причине не оба доступны во время компиляции, как это должно быть.
@MartinZeitler, это была проблема! Я понял это, глядя на плагины с помощью вас, ребята.
@DimasMendes Узнал, что работает только debugImplementation
, после того, как снова нашел свой собственный ответ.
Тебя не хватает
import org.mockito.junit.MockitoJUnitRunner
. Авторазрешение не работает из-за других ошибок в файле. Или в ваших зависимостях Gradle может что-то отсутствовать.