Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Unit Test throws NoClassDefFoundError on Log

I get a java.lang.NoClassDefFoundError: android/util/Log error when I try to run my unit test project in eclipse.

Distilled down, my test code looks like this:

package com.randomtype.yycparking;

import junit.framework.TestCase;
import android.util.Log;

public class StallTests extends TestCase {  
    public void setUp() {
        Log.v("HI", "Fail");
    }

    public void testShouldParseIdFromTitle() {
        assertTrue(true);
    }
}

And the code throws an exception on the Log.v call. When I run the android project normally I don't get any exceptions around Log.

Full Stack Trace:

java.lang.NoClassDefFoundError: android/util/Log
    at com.randomtype.yycparking.StallTests.setUp(StallTests.java:11)
    at junit.framework.TestCase.runBare(TestCase.java:132)
    at junit.framework.TestResult$1.protect(TestResult.java:110)
    at junit.framework.TestResult.runProtected(TestResult.java:128)
    at junit.framework.TestResult.run(TestResult.java:113)
    at junit.framework.TestCase.run(TestCase.java:124)
    at junit.framework.TestSuite.runTest(TestSuite.java:243)
    at junit.framework.TestSuite.run(TestSuite.java:238)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    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.util.Log
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 14 more

As pointed out by dtmilano, I wasn't running the unit tests as an Android JUnit Test. How can you tell the difference? Look for the little a like in the picture below:

Screen shot of a beside JUnit icon
(source: skitch.com)

like image 548
Gavin Miller Avatar asked Jan 11 '12 20:01

Gavin Miller


4 Answers

Your tests should be in a separate Android Test Project (Project -> Android Tools -> New Android Project) and you should run them as Android JUnit Test (Run as -> Android JUnit Test).

like image 55
Diego Torres Milano Avatar answered Sep 23 '22 16:09

Diego Torres Milano


Today when running the unit tests in my project, I hit this same error - over 100 of my unit tests were suddenly failing, even though they were working a week ago (without me doing any changes). The solution was to restart Android Studio. I think there's a bug in the 3.5.x versions of Android Studio where over time it can lose the configuration for running unit tests and will start throwing errors such as this one.

like image 26
Carl Anderson Avatar answered Sep 20 '22 16:09

Carl Anderson


 android {
  // ...
  testOptions { 
    unitTests.returnDefaultValues = true
  }
}

reference http://tools.android.com/tech-docs/unit-testing-support#TOC-Method-...-not-mocked.-

i find my issue: notify your build.gradle file ,you should set the compileSdkVersion equal 23 and the same as targetSdkVersion, it work well.

like image 38
ahsiu Avatar answered Sep 20 '22 16:09

ahsiu


I ran into this issue in the context of running JUnit tests for Android with mocks for the Log methods, since my unit tests should not have relied on Android's own implementation.

So I had mocks in test/java/android/util/Log.java – all except the Log.v method. After adding the v method in the mocks, everything worked again.

package android.util;

public class Log {
    public static int d(String tag, String msg) {
        System.out.println("DEBUG: " + tag + ": " + msg);
        return 0;
    }

    public static int i(String tag, String msg) {
        System.out.println("INFO: " + tag + ": " + msg);
        return 0;
    }

    public static int w(String tag, String msg) {
        System.out.println("WARN: " + tag + ": " + msg);
        return 0;
    }

    public static int e(String tag, String msg) {
        System.out.println("ERROR: " + tag + ": " + msg);
        return 0;
    }

    public static int v(String tag, String msg) {
        System.out.println("VERB: " + tag + ": " + msg);
        return 0;
    }
}
like image 45
slhck Avatar answered Sep 23 '22 16:09

slhck