我有一段代码接受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测试方法A(),以便我可以测试传递垃圾数据或在我的测试用例中抛出异常。
问题是我无法在android中模拟AssetManager类(它是Final)。
我尝试使用InstrumentationTestCase来注入实际和测试上下文,但这仅适用于少数场景。 如何控制BufferedInputStream以便我可以提供任何我想要的输入(使用模拟或其他方式)?
答案 0 :(得分:6)
我不得不处理同样的问题。这就是我在不使用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;
}
}
答案 1 :(得分:1)
尝试通过调用以下代码检索context
:
Context context = InstrumentationRegistry.getTargetContext();
BufferedInputStream is = new BufferedInputStream(context.getAssets().open("test.txt"));
答案 2 :(得分:0)
对于ProviderTestCase2
,在我的实现中调用context.getResources().getAssets()
而不是context.getAssets()
解决了该问题。否则,您想使用ApplicationProvider.getApplicationContext<Context>()
来获得一个Context
实例,该实例具有文件访问权限(在测试内部)。
Seems,ProviderTestCase2
使用RenamingDelegatingContext
将文件方法转发到未存根的方法,但是由于任何原因,context.getAssets()
都被省略了。我对新的测试材料还不够深入,无法确定其他类型的测试用例是否也会发生相同的情况。
AndroidX文档一团糟,我在阅读框架源代码只是为了找出自己在做什么。希望这对某人有帮助。