Android Studio上的自定义Android sdk和单元测试
我正在尝试使用Android Studio 2.2.2中的定制Android Sdk和com.Android.tools.build:gradle:2.2进行单元测试。但是我不断地遇到一些错误,无法克服它们,所以我想请求您的帮助。让我解释一下我做了什么,试着看看你是否能找到答案并帮助我 我用Android6(sdk 23)从Nexus5x中提取类,制作了一个定制的android.jar。这个jar包含隐藏的方法和内部类 完整自定义SDK 第一次尝试是创建一个完整的SDK。为此,我下载了SDK,安装了版本23,并用我的自定义jar替换了新的_SDK/platform/android-23/android.jar 在Android Studio中,我可以执行诸如assemble或install之类的任务来生成apk,但当我执行unitTest或任何包含“:app:mockableAndroidJar”任务的任务时,我会出现以下错误:Android Studio上的自定义Android sdk和单元测试,android,unit-testing,android-gradle-plugin,Android,Unit Testing,Android Gradle Plugin,我正在尝试使用Android Studio 2.2.2中的定制Android Sdk和com.Android.tools.build:gradle:2.2进行单元测试。但是我不断地遇到一些错误,无法克服它们,所以我想请求您的帮助。让我解释一下我做了什么,试着看看你是否能找到答案并帮助我 我用Android6(sdk 23)从Nexus5x中提取类,制作了一个定制的android.jar。这个jar包含隐藏的方法和内部类 完整自定义SDK 第一次尝试是创建一个完整的SDK。为此,我下载了SDK,安
Execution failed for task ':app:mockableAndroidJar' > java.lang.NullPointerException (no error message)
我想我之所以会出现这个错误,是因为定制sdk在方法中包含实现,并且没有像原始的android.jar那样的存根
自定义类似SDK的JAR依赖项
我尝试的第二个尝试是使用原始sdk并添加扩展的自定义sdk,如依赖项jar。在本例中,我在app build.gradle中添加jar,如下所示:
dependencies {
...
provided files('libs/android-full-23-nexus5x.jar')
...
}
AndroidStudio显示隐藏方法和常量的编译错误,因为无法解析符号,但它适用于内部类
问题是Android Sdk覆盖了我的自定义jar。为了解决这个问题,我在app.iml中更改了依赖项的顺序,因此:
...
<orderEntry type="library" exported="" name="android-full-23-nexus5x" level="project" />
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK"/>
...
通过添加root build.gradle解决了这个问题:
allprojects {
...
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add("-Xbootclasspath/p:app/libs/android-full-23-nexus5x.jar")
}
}
}
同步、清理和重建后,组装和安装任务可以工作,仅适用于实际的构建类型,但它可以工作
现在,我在没有模拟的情况下执行单元测试,如:
public class EmailValidatorTest {
@Test
public void emailValidator_CorrectEmailSimple_ReturnsTrue() {
assertTrue(EmailValidator.isValidEmail("name@email.com"));
}
}
这工作正常,但当我需要使用mock执行unitTest时,会失败:
public class MockUnitTest {
private static final String FAKE_STRING = "my_app_name";
@Mock
Context mMockContext;
@Test
public void readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
when(mMockContext.getString(R.string.app_name)).thenReturn(FAKE_STRING);
ClassUnderTest myObjectUnderTest = new ClassUnderTest(mMockContext);
// ...when the string is returned from the object under test...
String result = myObjectUnderTest.getHelloWorldString();
// ...then the result should be the expected one.
assertThat(result, is(FAKE_STRING));
}
}
我发现,如果我从app.iml文件中删除行
unitTest with mock works and assembly task,问题是AndroidStudio显示错误,因为无法解析符号。
这也不允许模拟隐藏方法
从命令行执行单元测试
当AndroiStudio执行unitTest时,命令为:
/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/bin/java -ea -Didea.launcher.port=7537 "-Didea.launcher.bin.path=/Applications/Android Studio.app/Contents/bin" -Didea.junit.sm_runner -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/Contents/lib/idea_rt.jar: ... :.../app/libs/android-full-23-nexus5x.jar: ... :.../build/generated/mockable-android-23.jar" com.intellij.rt.execution.application.AppMain com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 com.caseonit.pruebamockito.MockUnitTest,readStringFromContext_LocalizedString
AndroidStudio的结果是相同的错误,但是如果我更改classpath参数并在**mockable-android-23.jar*之后设置android-full-23-nexus5x.jar,结果是正确的
所以,我的问题是:是否可以为unitTest更改类路径?我试过了
android.unitTestVariants.all { variant ->
variant.javaCompile.classpath.minus(['/.../app/libs/android-full-23-nexus5x.jar'])
}
或者类似的,但都不起作用。
你有什么想法或建议吗?
非常感谢你。
致以最良好的祝愿
/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/bin/java -ea -Didea.launcher.port=7537 "-Didea.launcher.bin.path=/Applications/Android Studio.app/Contents/bin" -Didea.junit.sm_runner -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/Contents/lib/idea_rt.jar: ... :.../app/libs/android-full-23-nexus5x.jar: ... :.../build/generated/mockable-android-23.jar" com.intellij.rt.execution.application.AppMain com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 com.caseonit.pruebamockito.MockUnitTest,readStringFromContext_LocalizedString
android.unitTestVariants.all { variant ->
variant.javaCompile.classpath.minus(['/.../app/libs/android-full-23-nexus5x.jar'])
}