【问题标题】:Mocking Android AssetManager模拟 Android AssetManager
【发布时间】:2015-12-01 03:36:56
【问题描述】:

我有一段代码接受 Context 并将这个上下文传递给一个私有方法。 私有方法调用 getAssets().open() 来读取我应用的 assets 文件夹中的文件。

public void methodA(Context ctx) throws IOException{
     // do some stuff here...
     Object data[] = getFileContents(ctx);
     // use the data[] returned here...

}

private Object[] getFileContents(Context ctx) throws IOException{
     Object[] data;
     BufferedInputStream is = new BufferedInputStream(context.getAssets().open("test.txt"));
     // parse file and create array of Objects[]
     return data[];
}

我正在编写单元测试以使用 Mockito 测试 methodA(),以便我可以测试传递的垃圾数据或在我的测试用例中抛出异常。

问题是我无法在 android 中模拟 AssetManager 类(它是 Final)。

我尝试使用 InstrumentationTestCase 注入真实和测试上下文,但这仅适用于少数场景。 如何控制 BufferedInputStream 以便我可以提供任何我想要的输入(使用模拟或其他方式)?

【问题讨论】:

    标签: android unit-testing mockito


    【解决方案1】:

    对于ProviderTestCase2,在我的实现中调用context.getResources().getAssets() 而不是context.getAssets() 解决了这个问题。否则,您想使用ApplicationProvider.getApplicationContext<Context>() 来获取具有文件访问权限的Context 实例(在您的测试中)。

    Seems ProviderTestCase2 使用 RenamingDelegatingContext 将文件方法转发到未存根的方法,但无论出于何种原因,context.getAssets() 被省略了。我对新的测试内容还不够深入,无法确定其他类型的测试用例是否会发生同样的事情。

    AndroidX 文档一团糟,我正在阅读框架源代码只是为了了解我在做什么。希望这对某人有所帮助。

    【讨论】:

      【解决方案2】:

      尝试通过调用以下代码检索context

      Context context = InstrumentationRegistry.getTargetContext();
      BufferedInputStream is = new BufferedInputStream(context.getAssets().open("test.txt"));
      

      【讨论】:

        【解决方案3】:

        我不得不处理同样的问题。这就是我在不使用 Instrumentation 测试的情况下设法从我的单元测试程序访问配置文件的方式。 (我使用的是 Android Studio 2.1)。

        单元测试代码:

        public class ParametersTest {
        
            Parameters parameters = null;
        
            @Mock
            Context context;
            @Mock
            AssetManager assetManager;
            @Mock
            InputStream inputStream;
        
            @Before
            public void setUp() throws Exception {
                MockitoAnnotations.initMocks(this);//create all @Mock objetcs
                doReturn(assetManager).when(context).getAssets();
                //parametersandroid.xml is located in test/resources directory
                //parametersandroid.xml does not refer to a DTD file configuration.dtd
                //get the full path name of the file
                URL resource = ParametersTest.class.getClassLoader().getResource("parametersandroid.xml");
                // to be used  MyClass
                // inside the method I want to be tested there is this statement :
                // InputStream inputStream = this.assetManager.open(xmlFile);
                InputStream inputStream=new FileInputStream(resource.getPath());
                doReturn(inputStream).when(assetManager).open(anyString());
               // AssetManager assetManager = context.getAssets();
               // parameters = new Parameters(assetManager, resource.getPath());
                parameters = new Parameters(context, resource.getPath());
        
            }
            @Test
            public void testExtract() throws Exception {
               assertEquals(parameters.extract("//database/index[@name='TeamNameIdx']/create").replaceAll("[^a-z,A-Z,;,.,?,']", ""),"createindexTeamNameIdxonTeamEntnameasc;");
            }
        }
        

        要测试的类的代码:

        public class Parameters extends fr.acnice.valade.eric.gemara.utilities.Parameters {
            private AssetManager assetManager = null;
        
            public Parameters(Context context, String xmlFile) {
                super(xmlFile);
                this.assetManager = context.getAssets();
            }
            @Override
            public String extract(String request) throws XPathExpressionException,
                    Exception {
                InputStream inputStream = this.assetManager.open(super.xmlFile);
                String result = (String) xPath.evaluate(request, new InputSource(inputStream),
                        XPathConstants.STRING);
                if (result.isEmpty()) {
                    throw new Exception(
                            "Xpath result empty !!! check configuration file");
                }
                return result;
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-16
          • 2021-08-29
          • 2021-08-09
          • 1970-01-01
          • 2018-02-26
          相关资源
          最近更新 更多