【问题标题】:Unit test Android, getString from resource单元测试Android,从资源中获取字符串
【发布时间】:2016-09-19 15:24:20
【问题描述】:

我正在尝试对一个 android 应用程序进行单元测试,我需要从 res.string 资源中获取一个字符串。我要测试的类是 POJO 类。我正在用两种语言编写应用程序,因此,我需要从资源中获取一个字符串。问题是我无法获得上下文或活动,这可能吗?我知道使用 Instrumentation 测试我可以做到,但我需要先测试一些功能(白盒测试)才能进行 Instrumentation 测试(黑盒测试)。 这是我必须测试的功能:

public void setDiaByText(String textView) {
    getll_diaSeleccionado().clear();
    if (textView.contains(context.getResources().getString(R.string.sInicialLunes))) {
        getll_diaSeleccionado().add(0);
        getIsSelectedArray()[0] = true;
        getI_idiaSeleccionado()[0] =1;

    } else
    {
        getIsSelectedArray()[0] = false;
        getI_idiaSeleccionado()[0] =0;
    }
}

这是测试:

@Test
public void setDiaByTextView() {
    String texto = "L,M,X,J,V,S,D";

    alertaPOJO.setDiaByText(texto);

    assertEquals(alertaPOJO.getIsSelectedArray()[0], true);
    assertEquals(alertaPOJO.getI_idiaSeleccionado()[0], 1);
}

尝试执行context.getResources().getString(R.string.sInicialLunes))时崩溃

如果我输入“Mon”而不是 context.getResources().getString(R.string.sInicialLunes)) 或“L”,它可以完美运行,是否可以获取上下文或活动以访问资源文件夹?

我正在使用 Mockito 进行测试,setUp 函数是:

@Before
public void setUp() throws Exception {

    MockitoAnnotations.initMocks(this);
    mContext = Mockito.mock(Alerta.class);
    Mockito.when(mContext.getApplicationContext()).thenReturn(mContext);

    alertaPOJO = new AlertaPOJO();
}

谢谢

【问题讨论】:

    标签: android testing junit mockito


    【解决方案1】:

    如果您使用Context 仅用于获取String 资源,我会像这样只模拟getResources().getString() 部分(参见JUnit4 表示法):

    @RunWith(MockitoJUnitRunner.class)
    public class AlertaPOJOTest {
    
      @Mock
      Context mMockContext;
    
      @Test
      public void setDiaByTextView() {
         String texto = "L,M,X,J,V,S,D";
         when(mMockContext.getString(R.string.sInicialLunes))
           .thenReturn(INITIAL_LUNES);
    
    
         alertaPOJO.setDiaByText(texto);
    
         assertEquals(alertaPOJO.getIsSelectedArray()[0], true);
         assertEquals(alertaPOJO.getI_idiaSeleccionado()[0], 1);
       } 
    }
    

    继续使用 JVM 测试的原因有很多,最重要的是,它们运行得更快。

    【讨论】:

    • 获取此异常原因:io.mockk.proxy.MockKAgentException:无法为类 java.lang.String 创建代理。 class java.lang.String 是排除的类之一
    【解决方案2】:

    您在使用 JVM 单元测试时没有真正的 android 上下文。对于您的情况,也许您可​​以尝试 Android Instrumentation Test,通常它是在您项目的“androidTest”目录中实现的。

    【讨论】:

    • 谢谢@Sherlock,我想这是我读过的正确答案,但由于我是Android初学者,我需要确认一下。
    【解决方案3】:

    未经测试:使用以下内容是否可行,可能还有 targetContext?

    android {
       testOptions {
         unitTests {
            includeAndroidResources = true
         }
      }
    }
    

    【讨论】: