如何在单元测试中读取Android资源文件值

Erg*_*soy 2 android unit-testing mockito

我有一个数组资源。我想进行测试以读取和解析来自 xml 资源的值。这是代码。

<string-array name="names">
    <item>Name1[?]200</item>
    <item>Name2[?]125</item>
    <item>Name3[?]142</item>
</string-array>
Run Code Online (Sandbox Code Playgroud)

我想捕获上面的字符串资源并像下面的测试用例一样解析。但我达不到。

@RunWith(MockitoJUnitRunner.class)
public class ReadAndParseNamesTest {

@Mock
private Context mockApplicationContext;
@Mock
private Resources mockContextResources;

@Test
public void readAndParseNamesTest() {
    
    MockitoAnnotations.initMocks(this);

    when(mockApplicationContext.getResources()).thenReturn(mockContextResources);

     String[] marray = {"mock main class"};
    when(mockContextResources.getStringArray(R.array.allah_names))
            .thenReturn(marray);
    for(int i = 0;i<marray.length;i++){
        String[] deger = marray[i].split("[?]");
        System.out.println("Deger "+i+": "+deger[0] + " "+ deger[1]);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我收到java.lang.ArrayIndexOutOfBoundsException: 1异常,因为我无法获得实际值。任何帮助将不胜感激。谢谢你。

Tan*_*.7x 5

您不能使用简单的模拟来检索资源值。

考虑一下您同时拥有英语和法语字符串资源的情况——它应该解析哪个值?英语还是法语?在运行纯 JUnit 测试时,测试运行器不了解诸如此类的资源或如何解决它们。

您可以考虑几种方法。

选项 1:不要担心这些值
要问的第一个问题是您究竟在测试什么以及为什么。

您可能不需要测试 Android 框架是否正确加载了资源值。该框架有自己的测试套件,资源加载通常是可靠的。

如果您可以相信您的资源值是正确的,您只需要验证您是否getStringArray()使用正确的字符串 ID ( R.string.allah_names)进行调用。

选项 2:运行插桩测试
如果您真的想测试是否加载了正确的值,那么您需要使用实际的 Android 框架运行某种插桩测试。

这些测试在物理设备或模拟器上运行。

如果您想走那条路,请查看构建检测单元测试文档

选项 3:使用 Robolectric
作为插装测试和纯 Java 测试之间的中间地带,Robolectric提供了一个“假”Android SDK,可以解析资源、创建活动等。