Error java.lang.RuntimeException: Stub! in Android with Fitnesse testing
Asked Answered
L

4

31

I'm trying to create a test fixture using Fitnesse framework, and I want to test a function which retrieves data from a server (RESTFUL service). My test case is very simple:

public class FriendListActivityFixture extends ColumnFixture {
    public int URL;
    public String test() {
    JSONArray array = JsonHelper.getJsonArrayFromUrl("http://107.22.209.62/android/get_users.php");
    return array.toString();
    }
}

public static JSONArray getJsonArrayFromUrl(String url) {
        InputStream input = null;
        String result = "";
        JSONArray jsonArray = null;
        try {
            HttpClient httpclient = CustomHttpClient.getHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            input = entity.getContent();
        }
        catch (Exception e) {
            Log.e(TAG + ".getJsonArrayFromUrl(String url)", "Error in http connection " + e.toString()); 
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, "iso-8859-1"), 8);
            StringBuilder content = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                content.append(line + "\n");
            }
            input.close();
            result = content.toString();
        }
        catch (Exception e) {
            Log.e(TAG + ".getJsonArrayFromUrl(String url)", "Error parsing result " + e.toString());
        }

        try {
            jsonArray = new JSONArray(result);
        }
        catch (JSONException e) {
            Log.e(TAG + "getJsonArrayFromUrl(String url)", "Error converting data " + e.toString());
        }
        return jsonArray;
    }

And here is the Fitnesse test page:!path fitnesse.jar

!path C:\Program Files (x86)\Android\android-sdk\platforms\android-10\android.jar
!path C:\Users\chan\git\Spotr\Spotr\bin\classes

!|com.csun.spotr.fitnesse.FriendListActivityFixture|
|URL|test?|
|0|"wwa"|

Since it's just a demo, my test might look a bit silly at the moment. Unfortunately, I keep getting these errors:

java.lang.RuntimeException: Stub!
    at android.util.Log.e(Log.java:15)
    at com.csun.spotr.util.JsonHelper.getJsonArrayFromUrl(JsonHelper.java:75)
    at com.csun.spotr.fitnesse.FriendListActivityFixture.test(FriendListActivityFixture.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at fit.TypeAdapter.invoke(TypeAdapter.java:109)
    at fit.TypeAdapter.get(TypeAdapter.java:97)
    at fit.Fixture$CellComparator.compareCellToResult(Fixture.java:371)
    at fit.Fixture$CellComparator.access$100(Fixture.java:357)
    at fit.Fixture.compareCellToResult(Fixture.java:299)
    at fit.Fixture.check(Fixture.java:295)
    at fit.ColumnFixture.check(ColumnFixture.java:51)
    at fit.Binding$QueryBinding.doCell(Binding.java:215)
    at fit.ColumnFixture.doCell(ColumnFixture.java:37)
    at fit.Fixture.doCells(Fixture.java:171)
    at fit.Fixture.doRow(Fixture.java:165)
    at fit.ColumnFixture.doRow(ColumnFixture.java:25)
    at fit.Fixture.doRows(Fixture.java:159)
    at fit.ColumnFixture.doRows(ColumnFixture.java:18)
    at fit.Fixture.doTable(Fixture.java:153)
    at fit.Fixture.interpretTables(Fixture.java:99)
    at fit.Fixture.doTables(Fixture.java:79)
    at fit.FitServer.process(FitServer.java:81)
    at fit.FitServer.run(FitServer.java:56)
    at fit.FitServer.main(FitServer.java:41)

And I have no idea what is it telling me? I wrote other testing method like add(), substract(), everything worked fine. I wonder does this error involve running a long task on the main thread? Any idea?

Lewak answered 24/1, 2012 at 6:1 Comment(0)
S
52

android.jar contains only stub implementation of the classes. It provides the means for you app to build, once you have your APK you must run it on an android device or emulator.

If I'm not wrong you are trying to run on host's JVM.

Sorayasorb answered 24/1, 2012 at 6:51 Comment(6)
Thanks, my test fixture class doesn't contain any Activity code though, so I don't understand why I have to run it on the device. Anyway, let me try it run it on the device.Lewak
Did you mean you want to see my Log?Lewak
I'm seeing your log and that's what first line saysSorayasorb
Hi, I'm using EclEmma to get coverage from a test, and seem to be getting that issue as well. The impression I get from your answer is that this occurs because EclEmma isn't running with the emulator. Do you know of a way to get this to work?Midgard
I removed the jar cleaned the project and added it again and it worked!Aron
I first encountered this issue when using Log as well. I would call this (specifically the fact that Log throws an RTE) a rather severe violation of the principle of least surprise.Attainture
U
12

You can fix this problem and test within your IDE really easily by using Roboelectric.

As dtmilano said, you can't run Android code on your laptop as is, but Roboelectric basically substitutes the actual method implementations for the stubs in Android.jar.

Two things to watch out for if you go with this solution:

  • Make sure that your JAR import is above the Android JAR in your dependencies list if using IntelliJ

  • It defaults to blocking HTTP requests under the assumption that you don't actually want to change the state of a server somewhere. You can, however, disable this quite easily: Roboelectric.getFakeHttpLayer().interceptHttpRequests(false);

Ursine answered 21/7, 2013 at 6:35 Comment(0)
I
5

As mentioned previously, Android jars are not good for anything beyond compiling. Even most innocent things are stubbed out completely. But you can still use them in host VM unit tests with good mocking frameworks. My choice is jmockit:

Not sure whether it will work with Fitnesse though

Impanel answered 24/1, 2012 at 7:0 Comment(2)
Many thanks for the example. However I still think Fitnesse is a better way to write test, since it's easier to document along the way.Lewak
... but test functionality is still important. And it may be as well compatiblewith mocking frameworksImpanel
N
1

I had this same issue because of the "static" declaration. In my case, .build() caused the issue in a static variable. The simple solution was to not declare the variable static. It can be final. Try removing "static" from the getJsonArrayFromUrl method and see if it works.

Notability answered 17/12, 2019 at 4:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.