I have a piece of code that accepts Context and passes this context to a private method. The private method calls the getAssets().open() to read a file present in the assets folder of my app.
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[];
}
I am writing Unit tests to test the methodA() using Mockito so that i can test passing junk data or throw exceptions in my testcases.
The problem is that i cannot mock AssetManager class in android (it being Final).
I tried to use InstrumentationTestCase to inject real and test context, but that only works for few scenarios. How do I control the BufferedInputStream so that I can provide it any input I want (using mocks or otherwise) ?
I had to deal with the same problem. This is how I managed to access configuration file from my unit test programm without using Instrumentation test. (I use Android Studio 2.1).
Code of the unit test:
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;");
}
}
Code of the class to be tested :
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;
}
}
Try retrieving the context
by calling the codes below:
Context context = InstrumentationRegistry.getTargetContext();
BufferedInputStream is = new BufferedInputStream(context.getAssets().open("test.txt"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With