I'm getting this error while trying to use FragmentScenario in Android
error: package androidx.fragment.app.testing does not exist
import androidx.fragment.app.testing.FragmentScenario;
^
This is my simple Unit test example:
package com.example.myapplication;
import androidx.fragment.app.testing.FragmentScenario;
import android.os.Build;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
#RunWith(AndroidJUnit4.class)
#Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.P)
public class MainActivityTest {
#Test
public void testFragmentScenario() {
FragmentScenario<BlankFragment> scenario = FragmentScenario.launchInContainer(BlankFragment.class);
}
}
build.gradle(app):
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
def test_version = '1.2.0'
def fragment_version = '1.2.4'
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
testImplementation "androidx.test:core:$test_version"
testImplementation 'androidx.test.ext:junit:1.1.1'
testImplementation "androidx.test:runner:$test_version"
testImplementation "androidx.test:rules:$test_version"
testImplementation 'org.robolectric:robolectric:4.3'
}
What am I missing because a few months ago this piece of code works.
Check your build variants in Android Studio. It should be debug
It looks that you use the wrong way, try to change debugImplementation to testImplementation in build.gradle. Hope it will helpful to you.
Related
Good afternoon, I have a nullpointer exception when stubbing
package com.micheladrien.android.fresquerappel
import android.app.Application
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.micheladrien.fresquerappel.R
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.junit.MockitoJUnitRunner
#RunWith(MockitoJUnitRunner::class)
class MainViewModelTest {
#Rule
#JvmField
var instantTaskExecutorRule = InstantTaskExecutorRule()
#Mock
val applicationMock: Application = mock(Application::class.java)
#Before
fun setUpTaskDetailViewModel() {
`when`(applicationMock.getString(R.string.collage_climat)).thenReturn("Climat")
}
}
edit : I need to stub the function when(applicationMock.getString(R.string.collage_climat)).thenReturn("Climat")
because my viewmodel will get strings from context.
According to this blog post : https://codepills.com/2018/05/10/3-basic-mistakes-for-nullpointerexception-when-mock/
I should replace when thenreturn by when then (answer) which if it's true, why ?
I have already Tested : Changing R.id value to a brut number. => Same error
Mocking the file inside the before and using lateinit for the declaration at #Mock => same error
Unlike previous question thread Mockito - NullpointerException when stubbing Method
I am directly stubbing the method. Not stubbing the method of the object of another method.
Any help would be greatly appreciated.
Edit : The VM I aim to test :
class MainViewModel(application: Application): AndroidViewModel(application), WaitingViewModel{
private val _name = MutableLiveData<String>().apply {
value = application.getString(R.string.collage_climat)
}
val name : LiveData<String> = _name
override fun notifyNewCollage(collage_name: String) {
_name.value = collage_name
}
}
Here is the gradle if you want to check the Mockito version :
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.3'
def navigation_version = '2.3.1'
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.navigation:navigation-fragment:$navigation_version"
implementation "androidx.navigation:navigation-ui:$navigation_version"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
implementation 'il.co.theblitz:observablecollections:1.4.2'
def espressocore_version = '3.3.0'
androidTestImplementation "androidx.test.espresso:espresso-core:$espressocore_version"
androidTestImplementation "androidx.test.espresso:espresso-core:$espressocore_version"
androidTestImplementation "android.arch.core:core-testing:$lifecycle_version"
def mockito_version = '3.5.5' // For local unit tests on your development machine (also tested on 3.3.3)
testImplementation "org.mockito:mockito-core:$mockito_version" // For instrumentation tests on Android devices and emulators
androidTestImplementation "org.mockito:mockito-android:$mockito_version"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
}
Mockito advices against Mocking classes you don't own. So an Application mock is a bad idea.
Junit can give you the application context needed : https://developer.android.com/training/testing/junit-runner
For other info about stubbing fail, Mockito fails on stubbing : it tries to execute the function that should be stubbed
I am making some unit testing. but when i want to run that unit test it gave me error like this
"java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)"
what i am doing wrong?
this is my gradle. i wonder if i add wrong dependency into it, please help me :'(
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
multiDexEnabled true
applicationId "com.example.androidjetpacksubmission1"
minSdkVersion 15
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'
}
debug{
applicationIdSuffix ".debug"
debuggable true
}
}
testOptions {
unitTests.returnDefaultValues = true
}
androidExtensions {
experimental = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.github.bumptech.glide:glide:4.10.0'
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
implementation 'androidx.test.espresso:espresso-idling-resource:3.2.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
implementation 'com.facebook.shimmer:shimmer:0.5.0'
implementation "androidx.arch.core:core-testing:2.1.0"
implementation "org.mockito:mockito-android:3.1.0"
implementation 'androidx.multidex:multidex:2.0.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:core:1.2.0'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.ext:truth:1.2.0'
androidTestImplementation 'androidx.arch.core:core-testing:2.1.0'
androidTestImplementation 'com.google.truth:truth:0.42'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.2.0'
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.2.0'
androidTestImplementation 'com.android.support.test:runner'
androidTestImplementation group: 'org.mockito', name: 'mockito-core', version: '3.1.0'
androidTestImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.1.0'
testImplementation "androidx.arch.core:core-testing:2.1.0"
androidTestImplementation "org.mockito:mockito-android:3.1.0"
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
}
and this is my unit test code
package com.example.androidjetpacksubmission1.ui.detail
import androidx.lifecycle.Observer
import com.example.androidjetpacksubmission1.data.entity.TvShowEntity
import com.example.androidjetpacksubmission1.data.repository.RemoteRepository
import com.example.androidjetpacksubmission1.network.Network
import com.example.androidjetpacksubmission1.network.NetworkListener
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
class DetailTvShowViewModelTest : NetworkListener {
override fun onSuccess(msg: String) {
}
override fun onFailure(msg: String?) {
}
#get:Rule
var executorRule = androidx.arch.core.executor.testing.InstantTaskExecutorRule()
private lateinit var detailTvShowViewModel: DetailTvShowViewModel
private lateinit var remoteRepository: RemoteRepository
private lateinit var observer: Observer<*>
private val tvShowTitleExample = "Jumanji: The Next Level"
#Before
fun setup(){
observer = mock(Observer::class.java)
remoteRepository = RemoteRepository(Network.routes())
detailTvShowViewModel = DetailTvShowViewModel(remoteRepository,tvShowTitleExample)
detailTvShowViewModel.networkListener = this
}
#Test
fun getDetailMovie() {
detailTvShowViewModel.getDetailTvShow().observeForever(observer as Observer<in TvShowEntity>)
detailTvShowViewModel.fetchDetailTvShow()
verify(observer).onChanged()
}
}
private fun <T> Observer<T>.onChanged() {
}
When I try to use Configuration class android studio says "Cannot resolve symbol 'Configuration'". How can I use Configuration class appropriately?
Here is the class:
package android.example.com;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.runner.RunWith;
#RunWith(AndroidJUnit4.class)
public class ActivityInputOutputTest {
#Before
public void setup() {
Configuration config;
}
}
And Here's the build.gradle (Module: app):
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "android.example.com"
minSdkVersion 15
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'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation "androidx.work:work-testing:2.2.0"
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.12'
// Optional -- Robolectric environment
testImplementation 'androidx.test:core:1.0.0'
// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compileOnly 'com.jakewharton.espresso:espresso:1.1-r2'
androidTestCompile('com.jakewharton.espresso:espresso:1.1-r2') {
exclude group: 'com.squareup.dagger'
}
}
Add the following in your build.gradle
implementation "androidx.work:work-runtime:2.2.0"
I am trying to write my first test and I have problem figuring out the right dependencies to get everything to work. Here is my test class
class EmployeeDatabaseTest {
private lateinit var employeeDao: EmployeeDAO
#Before
fun setup() {
EmployeeDatabase.TEST_MODE = true
employeeDao = EmployeeDatabase.getDatabase(??).employeeDao()
}
#Test
fun should_Insert_Employee_Item() {
val employee = Employee("xx", "xx", 31, Gender.MALE)
employee.id = 1
runBlocking { employeeDao.addNewEmployee(employee) }
val employeeTest = runBlocking { getValue(employeeDao.getEmployeeById(employee.id!!)) }
Assert.assertEquals(employee.name, employeeTest.name)
}
}
Normally I would obtain context by InstrumentationRegistry.getContext()...but InstrumentationRegistry can't be resolved. It also can't resolve getValue(..) method. I am new to testing but I bet is something with dependencies. Here is my build.gradle:
dependencies {
...
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestImplementation 'androidx.test:core:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
}
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Do I miss something I am I doing something wrong?
A simple Context can be resolved with
androidx.test.core.app.ApplicationProvider.getApplicationContext()
which is part of the core module
androidTestImplementation 'androidx.test:core:1.2.0'
When you use Robolectric, you can also have it as
testImplementation 'androidx.test:core:1.2.0'
Android Studio 3.4.2
I has main project (app) that use module mytransport like this:
app/build.gradle
dependencies {
annotationProcessor "org.androidannotations:androidannotations:$AAVersion"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation('com.crashlytics.sdk.android:crashlytics:2.7.0#aar') { transitive = true; }
implementation 'com.google.android.material:material:1.1.0-alpha07'
implementation "org.androidannotations:androidannotations-api:$AAVersion"
implementation project(':mytransport')
}
In mytransport/build.gradle:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
}
In mytransport code I success use code like this:
in MyProject\mytransport\src\main\java\com\mycompany\android\mytransport\util\MyUtil.java
snippet:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class JSONUtil {
private static GsonBuilder gsonbuilder = new GsonBuilder();
Nice.
Now I want in main app to use gson lib.
So in main app I try this in
MyProject\android\MyProject\app\src\main\java\com\mycompany\android\myproject\main\MainApp.java
snippet
import android.app.Application;
import android.content.Context;
public class MainApp extends Application {
private static GsonBuilder gsonbuilder = new GsonBuilder();
but I get compile error:
Cannot resolve symbol 'GsonBuilder'
Why it can't find gson lib in main app? I use it TRANSITIVE by mytransport module
Use api instead of implementation.
In mytransport/build.gradle:
dependencies {
//...
api 'com.google.code.gson:gson:2.8.5'
}
Just an example.
In library/build.gradle:
dependencies {
api project(':libraryA')
}
In app/build.gradle:
dependencies {
api project(':library')
}
In your app you will be able to access both library and libraryA.
Using the implementation configuration:
In library/build.gradle:
dependencies {
implementation project(':libraryA')
}
In app/build.gradle:
dependencies {
implementation project(':library')
}
In this case in your app you can't access the libraryA methods.