0

I have a library of classes in my android workspace. I am now trying to test each class with JUnit and UNIT tests.

The first test I wrote for a pure java class in the library, and it ran smoothly.

The second test I wrote for a class that uses some android classes (Rect) and the test runs but fails with classNotFoundException when it has to instantiate a Rect field in the target class.

Here is the offending code (line 1161):

    1156        public Symbol(String name, int id) {
    1157            validateName(name);
    1158            this.name = name;
    1159            this.id = id;
    1160            this.value = null;
    1161            this.location = new Rect();
    1162            this.precedence = 0;
    1163            this.associativity = Associativity.PRECEDENCE;
    1164        }

This is the error message:

    java.lang.NoClassDefFoundError: android/graphics/Rect
        at com.Common.lib.Grammar$Symbol.<init>(Grammar.java:1161)
        at com.Common.lib.Grammar$Terminal.<init>(Grammar.java:1285)
        at com.Common.lib.Grammar$Terminal.<init>(Grammar.java:1284)
        at com.Common.lib.Grammar.createTerminal(Grammar.java:558)
        at com.Common.lib.Grammar.<init>(Grammar.java:77)
        at com.Common.lib.GrammarTest.testGrammar(GrammarTest.java:39)
        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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.ClassNotFoundException: android.graphics.Rect
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 30 more
ilomambo
  • 8,290
  • 12
  • 57
  • 106

1 Answers1

1

This is because your test classpath does not includes android classes. From the documentation (https://developer.android.com/tools/testing/testing_android.html) :

Android test suites are based on JUnit. You can use plain JUnit to test a class that doesn't call the Android API, or Android's JUnit extensions to test Android components. If you're new to Android testing, you can start with general-purpose test case classes such as AndroidTestCase and then go on to use more sophisticated classes.

If your code is a apklib (and not an application) , there two way of testing it. Quoting the documentation)

  • You can set up a test project that instruments an application project that depends on the library project. You can then add tests to the project for library-specific features.
  • You can set up a standard application project that depends on the library and put the instrumentation in that project. This lets you create a self-contained project that contains both the tests/instrumentations and the code to test.

http://developer.android.com/tools/projects/index.html#testing

As a bonus (not not mandatory) you can use roboelectric (http://robolectric.org/) to avoid java.lang.RuntimeException: Stub (but not ClassNotFoundException) exceptions and running your test without the emulator.

Pierre Rust
  • 2,474
  • 18
  • 15
  • When adding the android classes to the class path, I get an even earlier error (Invalid layout of java.lang.String at value), which is why I removed it in the first place (see http://stackoverflow.com/questions/13030111/fatal-error-invalid-layout-of-java-lang-string-at-value/13210088#13210088). And the test I was using was the automatic test template generated by JUnit, although I now changed it to AndroidTestCase I cannot tell you if it works, because of the aforementioned error I am getting now. – ilomambo Feb 24 '14 at 10:45
  • 1
    Did you create an android test project as explained here ? https://developer.android.com/tools/testing/testing_eclipse.html It adds an elements to your manifest. Or are your test classes defined in the same project than your application ? – Pierre Rust Feb 24 '14 at 11:06
  • I did create the test project from scratch as described in the Developer's site, same link you gave in your last comment. Now the error is that the Instrumentation cannot find the target package apk, which does not exist because my target project is a Library, not an Application, a jar exists, which I tried to add to the build path, but it did not solve the problem. – ilomambo Feb 24 '14 at 13:30
  • I followed all the recommendations and still I am failiing, I describe all I did in detail in a new post (http://stackoverflow.com/questions/21992150/ordeal-trying-to-use-junit-to-test-a-library) – ilomambo Feb 24 '14 at 15:40