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