gpt4 book ai didi

android - junit4 使用 mockito 打开 getResources().openRawResource 运行 nullpointer

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:15:24 26 4
gpt4 key购买 nike

android studio 2.1. preview 4

我正在创建一个 junit4 单元测试 来测试打开原始目录中包含的文件。

但是,每次代码运行时,我都可以从 openRawResource 获取一个空指针。

这是我要测试的功能。这在实际设备上运行时有效。但不在单元测试中。

public String getNewsFeed(Context mContext) {
InputStream inputStream = mContext.getResources().openRawResource(R.raw.news_list); // Null pointer

Writer writer = new StringWriter();
char[] buffer = new char[1024];

try {
InputStreamReader inputReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferReader = new BufferedReader(inputReader);
int n;
while ((n = bufferReader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}

inputStream.close();
}
catch (IOException ioException) {
return "";
}

return writer.toString();
}

这是我的测试用例

@RunWith(MockitoJUnitRunner.class)
public class NewsListPresenterTest {

@Mock
private Context mContext;
@Mock
private NewsListPresenter mNewsListPresenter;

@org.junit.Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mNewsListPresenter = new NewsListPresenter(mContext);
}

@org.junit.Test
public void testLoadNewsFeed() throws Exception {
assertNotNull(mNewsListPresenter.getNewsFeed(mContext));
}
}

非常感谢您的任何建议,

最佳答案

您混淆了 Android 中的两种单元测试。很多人不清楚,所以我将在这里解释一下。

为什么它在设备上有效:因为这是一个插桩测试。什么是仪器化测试?在真实设备/模拟器上运行的测试,测试代码位于“src/androidTest”文件夹中。

为什么它不能用作本地 junit 测试:因为本地 junit 测试不是插桩测试。本地 Junit 测试在计算机的 JVM 上运行,而不是在设备上运行。本地 Junit 测试不应包含/使用 Android 代码,因为真正的 Android 代码在设备/模拟器上,而不是在您计算机的 JVM 上。

我想您想让它作为 junit 测试运行以更快地运行,这就是为什么我想您将测试移至“src/test”文件夹并且 context.getResources() 抛出 NullPointerException。

我认为您在这里有 2 个选择:

  1. 使用Robolectric将此测试作为 junit 测试运行
  2. 重构您的方法,使其不依赖于 Android 的类

对于选项 2,这就是我会做的。将方法的参数更改为 InputStream:

public String getNewsFeed(InputStream inputStream) {... use inputStream... }

现在您的方法看不到任何 Android 代码,您可以将其作为普通的 junit 方法进行测试。然后,您可以将伪造的 inputStream 传递给您的方法,如下所示:

@Test
public void testLoadNewsFeed() throws Exception {
String fileContents = "line one";
InputStream inputStream = new ByteArrayInputStream(fileContents.getBytes());
assertNotNull(mNewsListPresenter.getNewsFeed(inputStream));
}

如果您仍想传递与您在应用中使用的相同的 inputStream(我不推荐),您仍然可以在测试中使用此代码:

@Test
public void testLoadNewsFeed() throws Exception {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("raw/news_list");
assertNotNull(mNewsListPresenter.getNewsFeed(inputStream));
}

并且您必须将此行添加到您的 build.gradle 文件中:

sourceSets.test.resources.srcDirs += ["src/main"]

Android 单元测试可能非常困惑。您可以在 this 中阅读这些概念我写的博文

关于android - junit4 使用 mockito 打开 getResources().openRawResource 运行 nullpointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36239011/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com