对于我的Android应用程序,我正在编写需要读取一些文件的单元测试。 由于这些是仅测试文件,因此我不希望它们出现在res文件夹中,因为我不希望它们最终出现在最终的.apk文件中。
我想做与此问题类似的事情,但要使用新添加的(在Gradle 1.1中)单元测试支持(而不是仪器测试)。
我的项目结构如下:
/app
/src
/main
/java/my.module/myClass.java
/res/production_resources_go_here
/test
/java/my.module/myClassTest.java
/resources/testFile.txt
我的myClassTest测试应该如何才能成功读取testFile.txt?
我认为我们需要查看更多代码供myClass.java对此发表评论。 您想让测试将testFile.txt传递给处理myClass中文本文件的任何方法,然后检查(用AssertJ声明)结果是否按预期返回。 研究Robolectric和Mockito可能会给您一些想法。
myClass.java无关紧要。 假设它有一个消耗InputStream的方法,并且我希望流在测试中包含文件中的内容。 那有意义吗?
如果您想对此进行一些修改,请阅读"我的帖子"。 您可以在手机内打开apk,然后将其读取为流
在问这个问题的时候,这根本行不通。幸运的是,此后已解决。
OP必须尝试将文本文件放在app/src/test/resources文件夹下。此外,它必须与您的测试班级放在同一包中。因此,如果您在app/src/test/java文件夹中的com.example.test软件包中包含ReadFileTest.java,则您的测试文件应位于app/src/test/resources/com/example/test中。
然后,您可以像这样进入文本文件:
getClass().getResourceAsStream("testFile.txt")
这将打开文本文件的InputStream。如果不确定如何处理它,可以使用以下几种方法:将InputStream读取/转换为String
FWIW我认为现在可以正常工作了。 如果有兴趣,我可以仔细检查并编辑答案以显示如何加载文件。
是的,我有兴趣,请示范。
如果可以的话,我会投票100次。 关键实际上是正确的道路。 谢谢谢谢! :D
如果某人在使InputStream结果为null时遇到问题,请添加斜杠,例如getClass().getResourceAsStream(;quot;;#47;testFile.txt;quot;)。
对于那些为输入流留有null的用户的另一个提示,请确保在创建资源的目录路径(例如com.example.test)时不要添加点。 当使用点而不是资源目录创建时,Android Studio将在java文件夹内自动创建目录
将此添加到您的build.gradle中:
android {
sourceSets {
test {
resources.srcDirs += ['src/test/resources']
}
androidTest {
resources.srcDirs += ['src/androidTest/resources']
}
}
}
为了使单元测试可以访问资源,请在以下位置添加文件:src/test/resources。
对于仪器测试,将文件添加到:src/androidTest/resources。
紧跟@Deepansu的答案,我统一了{project root}/sampledata目录中的测试数据,该目录是Android Studio Newp;gt; Sample Data Directory命令的默认位置。
1.在您的项目中,右键单击并单击Newp;gt; Sample Data Directory。这将在app中创建sampledata目录,该目录与build.gradle文件,src和build目录具有相同的层次结构。
2.在build.gradle中,添加如下脚本;
android {
sourceSets {
test {
resources.srcDirs += ['sampledata']
}
androidTest {
resources.srcDirs += ['sampledata']
}
}
}
3. gradle中的Sync。
现在,我们可以将测试资源文件放在一个目录中,并在两个测试环境中使用它们。
您可以阅读以下文件;
// use somewhere at test logic. Note that slash symbol is required (or not).
jsonObject = new JSONObject(readFromFile("/testFile.json"));
// a method to read text file.
public String readFromFile(String filename) throws IOException {
InputStream is = getClass().getResourceAsStream(filename);
StringBuilder stringBuilder = new StringBuilder();
int i;
byte[] b = new byte[4096];
while ((i = is.read(b)) != -1) {
stringBuilder.append(new String(b, 0, i));
}
return stringBuilder.toString();
}
这有效,而且超级简单。 谢谢
我正在一个结构类似于您提到的项目。
我将所有服务器响应都放在resources文件夹(如app/src/test/resources/BookingInfo.json)下的文件中。
所有Java测试文件都在app/src/test/java/PACKAGE_NAME下,与您所说的相似。我在包含资源名称的包下有一个Fixture类:
@SuppressWarnings("nls")
public final class Fixtures
{
public static final String GET_ANNOUNCEMENT ="GetAnnouncement.json";
...
}
最后是一个FixtureUtils类,该类的方法负责读取资源文件并返回结果。
import java.nio.file.Files;
import java.nio.file.Paths;
public class FixtureUtils
{
public static final AFixture fixtureFromName(final String fixtureName)
{
final String fixtureString = FixtureUtils.stringFromAsset(fixtureName);
if (StringUtils.isEmpty(fixtureString))
{
return null;
}
final Gson gson = new Gson();
final AFixture aFixture = gson.fromJson(fixtureString, AFixture.class);
return aFixture;
}
private static final String stringFromAsset(final String filename)
{
try
{
final URL resourceURL = ClassLoader.getSystemResource(filename);
if (resourceURL == null)
{
return null;
}
final String result = new String(Files.readAllBytes(Paths.get(resourceURL.toURI())),
Charset.forName("UTF-8")); //$NON-NLS-1$
return result;
}
catch (final Exception e)
{
e.printStackTrace();
}
return null;
}
private FixtureUtils()
{
// Ensure Singleton
}
}
AFixture类看起来像:
public class AFixture
{
public List validItems;
public List invalidItems;
public AFixture()
{
super();
}
public List getInvalidItems()
{
return this.invalidItems;
}
public List getValidItems()
{
return this.validItems;
}
public void setInvalidItems(final List invalidItems)
{
this.invalidItems = invalidItems;
}
public void setValidItems(final List validItems)
{
this.validItems = validItems;
}
}
注意:如果我没有记错的话,java.nio.file已从JDK8中删除,但是如果您使用的是JDK7,则没有问题。如果您使用的是JDK8,则只需以FileInputStream(旧时尚样式)或Scanner之类的方式更改stringFromAsset方法。
正确方法的一个示例是将文件放在资产文件夹中。但是,资产文件夹的内容将添加到apk中。
InputStream is = resources.getAssets().open("test.txt");
您可以欺骗该系统并遍历项目中的任何其他文件。确保在项目的iml文件中指定的位置(例如src / main / assets)中创建资产目录。
InputStream is = resources.getAssets().open("../../test/resources/testFile.txt");
获取资源的方法的一个示例是:
Resources resources = new Activity().getResources();