当前位置: 首页 > 知识库问答 >
问题:

如何与ContentValue单元测试总是null vs方法getAction在android.content.意图不嘲笑

钱和平
2023-03-14

最近我一直在使用最新的android工作室进行单元测试,它是3 beta 6,我发现即使我初始化了ContentValures它也是空的。我需要它实际上是一个值/init-edContentValue

我的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'
}

但是等等,还有更多!

我还有一个简单的测试:

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!
    }
}

所以我尝试了一个默认的gradle文件,发现contentvalues不是null。

以下是文件:

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'
}

老实说,我现在不太了解gradle,但我知道我的配置,这是一堆支持dagger和其他价值观的想法,从任何角度来说都不是很好。

在尝试其他事情后,我发现这是罪魁祸首:

testOptions {
    unitTests.returnDefaultValues = true
}

我想出了我有这个的原因。我在另一个领域有一个测试,那就是测试意图,我需要默认值。

是否有办法将其限制为排除ContentValues,或者反过来不包括Intent?

共有2个答案

邓开济
2023-03-14

您需要模拟构造函数,这可以通过PowerMock完成:

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

之所以会出现这种情况,是因为在测试开始时,Android还没有被实例化——此时您只运行普通Java,这有助于这些单元测试运行得非常快。

请记住,如果您试图在实际的源代码中调用ContentValues(),还必须准备调用构造函数的类,如下所述:

@PrepareForTest({ClassWhereContentValuesIsInitialized.class})

退一步说,使用Robolectric是UI端到端测试的优秀工具,但它目前不允许像Mockito/Powermock那样进行复杂的模拟。这两个框架用于完全不同的目的,并且都可以串联使用,但从技术上讲,切换到机器人分子并不能解决所提出的问题。

诚然,为Android设置Mockito是一件痛苦的事情,因为很多样板Android逻辑通常都需要模拟出来,有些人可能会争辩说复杂的逻辑无论如何不应该完全存在于客户端Android代码中,或者反对一般的单元测试。尽管如此,它可能是适合您的用例的正确工具。

衡玄裳
2023-03-14

好吧,它已经解决了。在撰写本文时,您仍然无法针对ContentValueIntents等android内容类进行单元测试。

正因为如此,我引入了Robolectic。这并不难,但以下是更改。

gradle文件

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

测试:

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);
    }
}
 类似资料:
  • 我需要设置/添加照片/电影作为ToDo应用程序的附件。不幸的是:onActivityResult in line super。onActivityResult(请求代码、结果代码、数据);以红色突出显示,我得到一个错误: 无法解析方法“onActivityResult(int,int,android.content.Intent)” ctivity.java

  • 我遇到了一个挑战,当我单独运行测试时,测试通过了,但当我运行所有测试时,测试失败了,它会显示以下错误消息: java.lang.RuntimeException:Android.os.Looper中的方法getMainLooper未被嘲弄。详见http://g.co/androidstudio/not-mocked。 在Android.os.looper.GetMainLooper(looper.

  • 因为save是一个void方法。 有人知道如何修复这个单元测试吗?

  • 我读到过嘲弄一切是不好的 测试气味:一切都被嘲弄 嘲弄一切是一个好办法 我还读到单元测试关注单个组件,而集成测试则测试整个系统的协同工作<编写优秀的单元测试:最佳和最差实践 这让我困惑。据我所知,要编写一个合适的单元测试,需要通过模拟除SUT之外的所有组件来隔离单个组件。如果在整个测试过程中使用真实对象,那么该测试不是成为一个集成测试吗? 一个人如何编写一个好的(独立的)单元测试而不去嘲笑一切?

  • Java 8,但这是一个通用的单元测试问题,它(很可能)是与语言无关的。 编写JUnit测试的语法很容易,但是决定要编写什么测试以及如何测试主/生产代码是我发现的最大挑战。在阅读单元测试最佳实践时,我一遍又一遍地听到同样的事情: 测试合同 我相信这个想法是,单元测试不应该是脆弱的,如果方法的实现发生变化,它不应该被破坏。该方法应定义输入的协定 - 假设我有以下方法: 所以在这里,我们有一个方法,我

  • 我有使用vue cli 3的vue应用程序。在安装过程中,我选择了jest作为测试框架。要运行我的单元测试,我在package.json中有一个脚本: 要运行这个我写在vs代码终端: 这将运行所有符合package.json文件jest配置部分中设置的规范的测试。 我的问题是如何只运行一个测试。我需要运行特定的命令吗?或者是否有一个vscode扩展将与此设置一起工作。