0

Récemment, j'ai fait des tests unitaires en faisant une mise à jour en utilisant le dernier studio android, qui est 3 beta 6, et j'ai trouvé que même lorsque j'initialise un ContentValues, il est nul. Je en ai besoin pour être réellement une valeur/init-ed ContentValues.Comment tester unitairement avec ContentValues ​​toujours null vs Méthode getAction dans android.content.Intent pas mocké

mon fichier gradle:

apply plugin: 'com.android.application' 

android { 

    compileSdkVersion 26 
    buildToolsVersion "26.0.1" 
    defaultConfig { 
     applicationId "com.cubedelement.soundplanner" 
     minSdkVersion 21 
     targetSdkVersion 26 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "org.mockito.testInstrumentationRunner" 
     vectorDrawables.useSupportLibrary = true 
    } 

    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
    compileOptions { 
     targetCompatibility 1.8 
     sourceCompatibility 1.8 
    } 

    testOptions { 
     unitTests.returnDefaultValues = true 
    } 
} 
dependencies { 
    implementation fileTree(dir: 'libs', include: ['*.jar']) 
    implementation 'com.android.support:palette-v7:26.1.0' 
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.0', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 

    implementation 'com.google.dagger:dagger-android:2.11' 
    implementation 'com.google.dagger:dagger-android-support:2.11' // if you use the support libraries 
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.11' 
    annotationProcessor 'com.google.dagger:dagger-compiler:2.11' 

    androidTestImplementation 'com.android.support.test:runner:1.0.1' 
    androidTestImplementation 'com.android.support.test:rules:1.0.1' 
    implementation 'com.android.support:appcompat-v7:26.1.0' 
    implementation 'com.google.code.gson:gson:2.8.0' 
    testImplementation 'junit:junit:4.12' 
    testImplementation 'org.powermock:powermock-api-mockito2:1.7.0' 
    testImplementation 'org.powermock:powermock-module-junit4:1.6.5' 
    implementation 'com.android.support:design:26.1.0' 
    implementation 'com.android.support.constraint:constraint-layout:1.0.2' 
    testImplementation 'org.mockito:mockito-core:2.8.47' 
    androidTestImplementation 'org.mockito:mockito-core:2.8.47' 
} 

mais attendez, il y a plus!

J'ai aussi un test simple qui est:

import android.content.ContentValues; 

public class Test { 
    @Test public void ContentValuesShouldNotBeNull(){ 
     ContentValues v = new ContentValues(); 
     assertEquals(v, null) // this is true, but I don't want it to be, help! 
    } 
} 

est la vue ici en studio android android beta showing null for content values

J'ai essayé un fichier gradle par défaut et a constaté que contentValues ​​est pas nul.

voici le fichier:

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 26 
    buildToolsVersion '26.0.1' 
    defaultConfig { 
     applicationId "com.example.kelly_vernon.myapplication" 
     minSdkVersion 19 
     targetSdkVersion 26 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
} 

dependencies { 
    implementation fileTree(include: ['*.jar'], dir: 'libs') 
    implementation 'com.android.support:appcompat-v7:26.1.0' 
    implementation 'com.android.support.constraint:constraint-layout:1.0.2' 
    testImplementation 'junit:junit:4.12' 
    androidTestImplementation 'com.android.support.test:runner:1.0.1' 
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 
} 

Honnêtement, je ne comprends pas Gradle beaucoup à ce moment, mais je ne sais que ma config, qui est un tas d'idées pour soutenir dague et d'autres valeurs est pas génial par aucun effort.

Après avoir essayé d'autres choses, je trouve que ce soit le coupable:

testOptions { 
    unitTests.returnDefaultValues = true 
} 

je compris la raison pour laquelle j'ai eu cela. J'ai un test dans un autre domaine qui teste les intentions, et j'ai besoin de la valeur par défaut.

Existe-t-il un moyen de limiter cela à exclure ContentValues ou l'inverse de ne pas inclure le Intent?

Répondre

0

Eh bien, c'est résolu. Au moment de la rédaction de ce document, vous ne pouvez toujours pas effectuer de tests unitaires sur des classes de contenu Android comme ContentValues et Intent s. Pour cette raison, j'ai introduit Robolectric. Ce n'est pas difficile, mais voici les changements.

le fichier gradle:

testOptions { 
    unitTests { 
     returnDefaultValues = true 
     includeAndroidResources = true // new line 
    } 
} 

Le test:

import android.content.ContentValues; 

@RunWith(RobolectricTestRunner.class) //new line to start robolectric 
public class Test { 
    @Test public void ContentValuesShouldNotBeNull(){ 
     ContentValues v = new ContentValues(); 
     assertNotNull(v, null); 
    } 
} 
+0

Vous pouvez effectuer des tests unitaires sous Android à l'aide de PowerMock ou d'autres frameworks. – jbass

0

Vous devez se moquer du constructeur, qui peut être accompli avec PowerMock:

PowerMockito.whenNew(ContentValues.class).withNoArguments() 
      .thenReturn(mockContentValues);` 

Cela se produit parce que Android n'a pas été instancié lorsque votre test commence - vous n'utilisez que Java à ce stade, ce qui aide ces tests unitaires sont très rapides.

Gardez à l'esprit si vous essayez d'appeler contentValues ​​() dans le code source, vous devez également préparer la classe où le constructeur est appelé, comme cela est expliqué here:

@PrepareForTest({ClassWhereContentValuesIsInitialized.class}) 

Reculant une seconde , en utilisant Robolectric est un excellent outil pour les tests de bout en bout de l'interface utilisateur, mais il ne permet pas actuellement de se moquer de complexes comme le fait Mockito/Powermock. Les deux frameworks sont utilisés à des fins totalement différentes, et les deux peuvent être utilisés en tandem - mais le simple passage à Robolectric n'est pas techniquement une solution au problème posé. Certes, Mockito est pénible à configurer pour Android, car il faut généralement se moquer de la logique Android, et certains pourraient argumenter que la logique complexe ne devrait pas vivre complètement dans le code Android du côté client, ou s'opposer aux tests unitaires en général. Pourtant, il pourrait être le bon outil pour votre cas d'utilisation.