在单元测试执行期间如何从资产文件夹访问文件?我的项目是使用Gradle构建的,我使用Robolectric运行测试.毕业生似乎正在认识资产:
这是我如何努力阅读文件:
public String readFileFromAssets(String fileName) throws IOException { InputStream stream = getClass().getClassLoader().getResourceAsStream("assets/" + fileName); Preconditions.checkNotNull(stream,"Stream is null"); BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"UTF-8")); return IoUtils.toString(reader); }
但是流始终为空.我尝试了许多不同的方法,即使用不同方法定义到文件的路径.
提前非常感谢你.
解决方法
基本上你必须使用上下文来读取资产.您不能使用ClassLoader加载资源,因为它不在类路径中.我不知道你如何运行Robolectric测试用例.这是我在Android studio和gralde命令中如何实现的.
我在应用程序项目中添加了单独的应用程序单元测试模块来运行Robolectric测试用例.
通过正确的构建配置和定制的RobolectricTestRunner,以下测试用例将通过.
@Config @RunWith(MyRobolectricTestRunner.class) public class ReadAssetsTest { @Test public void test_ToReadAssetsFileInAndroidTestContext() throws IOException { ShadowApplication application = Robolectric.getShadowApplication(); Assert.assertNotNull(application); InputStream input = application.getAssets().open("b.xml"); Assert.assertNotNull(input); } }
APP-单元测试/的build.gradle
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.14.1' } } apply plugin: 'java' evaluationDependsOn(':app') sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 repositories { maven { url "$System.env.ANDROID_HOME/extras/android/m2repository" } // Fix 'com.android.support:*' package not found issue mavenLocal() mavenCentral() jcenter() } dependencies { testCompile 'junit:junit:4.8.2' testCompile('org.robolectric:robolectric:2.4') { exclude module: 'classworlds' exclude module: 'commons-logging' exclude module: 'httpclient' exclude module: 'maven-artifact' exclude module: 'maven-artifact-manager' exclude module: 'maven-error-diagnostics' exclude module: 'maven-model' exclude module: 'maven-project' exclude module: 'maven-settings' exclude module: 'plexus-container-default' exclude module: 'plexus-interpolation' exclude module: 'plexus-utils' exclude module: 'wagon-file' exclude module: 'wagon-http-lightweight' exclude module: 'wagon-provider-api' exclude group: 'com.android.support',module: 'support-v4' } testCompile('com.squareup:fest-android:1.0.+') { exclude group: 'com.android.support',module: 'support-v4' } testCompile 'org.mockito:mockito-core:1.10.10' def appModule = project(':app') testCompile(appModule) { exclude group: 'com.google.android' exclude module: 'dexmaker-mockito' } testCompile appModule.android.applicationVariants.toList().first().javaCompile.classpath testCompile appModule.android.applicationVariants.toList().first().javaCompile.outputs.files testCompile 'com.google.android:android:4.1.1.4' /* FIXME : prevent Stub! error testCompile files(appModule.plugins.findPlugin("com.android.application").getBootClasspath()) */ compile project(':app') }
添加自定义RobolectricTestRunner来调整文件路径.
看资产的路径.
public class MyRobolectricTestRunner extends RobolectricTestRunner { private static final String APP_MODULE_NAME = "app"; /** * Creates a runner to run {@code testClass}. Looks in your working directory for your AndroidManifest.xml file * and res directory by default. Use the {@link org.robolectric.annotation.Config} annotation to configure. * * @param testClass the test class to be run * @throws org.junit.runners.model.InitializationError if junit says so */ public MyRobolectricTestRunner(Class<?> testClass) throws InitializationError { super(testClass); System.out.println("testclass="+testClass); } @Override protected AndroidManifest getAppManifest(Config config) { String userDir = System.getProperty("user.dir","./"); File current = new File(userDir); String prefix; if (new File(current,APP_MODULE_NAME).exists()) { System.out.println("Probably running on AndroidStudio"); prefix = "./" + APP_MODULE_NAME; } else if (new File(current.getParentFile(),APP_MODULE_NAME).exists()) { System.out.println("Probably running on Console"); prefix = "../" + APP_MODULE_NAME; } else { throw new IllegalStateException("Could not find app module,app module should be \"app\" directory in the project."); } System.setProperty("android.manifest",prefix + "/src/main/AndroidManifest.xml"); System.setProperty("android.resources",prefix + "/src/main/res"); System.setProperty("android.assets",prefix + "/src/androidTest/assets"); return super.getAppManifest(config); } }
我跟着这个博客来做.
http://blog.blundell-apps.com/android-gradle-app-with-robolectric-junit-tests/
http://blog.blundell-apps.com/how-to-run-robolectric-junit-tests-in-android-studio/