android studio 2.1. preview 4
i creating junit4 unit test
test opening file contained in raw directory.
however, everytime code runs can null pointer openrawresource
.
this function trying test. works when running on actual device. not in unit test.
public string getnewsfeed(context mcontext) { inputstream inputstream = mcontext.getresources().openrawresource(r.raw.news_list); // null pointer writer writer = new stringwriter(); char[] buffer = new char[1024]; try { inputstreamreader inputreader = new inputstreamreader(inputstream, "utf-8"); bufferedreader bufferreader = new bufferedreader(inputreader); int n; while ((n = bufferreader.read(buffer)) != -1) { writer.write(buffer, 0, n); } inputstream.close(); } catch (ioexception ioexception) { return ""; } return writer.tostring(); }
this test case
@runwith(mockitojunitrunner.class) public class newslistpresentertest { @mock private context mcontext; @mock private newslistpresenter mnewslistpresenter; @org.junit.before public void setup() throws exception { mockitoannotations.initmocks(this); mnewslistpresenter = new newslistpresenter(mcontext); } @org.junit.test public void testloadnewsfeed() throws exception { assertnotnull(mnewslistpresenter.getnewsfeed(mcontext)); } }
many suggestions,
you confusing 2 types of unit tests in android. not clear many people i'll explain here.
why works on device: because instrumented test. instrumented test? test runs on real device/emulator , test code in 'src/androidtest' folder.
why doesn't work local junit test: because local junit tests not instrumented tests. local junit tests run on computer's jvm, not on device. local junit tests shouldn't contain/use android code because real android code on device/emulator, not on computer's jvm.
i suppose want make run junit test run faster, , that's why suppose moved test 'src/test' folder , context.getresources() throwing nullpointerexception.
i think have 2 options here:
- use robolectric run test junit test
- refactor method doesn't depend on android's classes
for option 2, do. change method's argument inputstream:
public string getnewsfeed(inputstream inputstream) {... use inputstream... }
now method doesn't see android code , can test normal junit method. pass fake inputstream method, this:
@test public void testloadnewsfeed() throws exception { string filecontents = "line one"; inputstream inputstream = new bytearrayinputstream(filecontents.getbytes()); assertnotnull(mnewslistpresenter.getnewsfeed(inputstream)); }
if still want pass same inputstream you're using in app (i wouldn't recommend it) still can using code in test:
@test public void testloadnewsfeed() throws exception { inputstream inputstream = this.getclass().getclassloader().getresourceasstream("raw/news_list"); assertnotnull(mnewslistpresenter.getnewsfeed(inputstream)); }
and you'll have add line build.gradle file:
sourcesets.test.resources.srcdirs += ["src/main"]
android unit tests can confusing. can read these concepts in this blog post wrote
Comments
Post a Comment