I'm attempting to build a unit test on Android which utilizes the mockito-all-1.8.5.jar file from mockito.org. I added the jar file to my project using project > properties > project build path > add external jar. This has always worked for me on non-Android java projects.
However, when I run the unit test, I get the following class not found exception:
java.lang.ClassNotFoundException: org.mockito.runners.VerboseMockitoJUnitRunner
Above it is the following message:
Cannot load class. Make sure it is in your apk. Class name: 'org.mockito.runners.VerboseMockitoJUnitRunner'. Message: org.mockito.runners.VerboseMockitoJUnitRunner
I checked the jar and the class is there.
I also tried adding according to this link:
How to use and package a JAR file with my Android app?
But, still no luck. How can I get this class to be found?
Edit: I'm thinking there is a problem with whatever libraries Mockitto depends on - they may not be compatible with the Dalvik jvm. See this post:
http://daverog.wordpress.com/2009/12/14/why-android-isnt-ready-for-tdd-and-how-i-tried-anyway/
1) Import a mocking framework (e.g. mockito) into the project as an additional dependency.
Any imported jars containing class files not compiled to Dalvik bytecode (most) will not work. Attempting to compile the source along with your project will not work either because most libraries will make extensive use of parts of the Java language not compatible with Dalvik: it uses its own library built on a subset of the Apache Harmony Java implementation.
If you are executing inside the Dalvik JVM you won't be able to use Mockito.
If you are running your unit tests on your desktop JVM however (with a testing framework like Robolectric for example) then you are good to go. I am combining the two on my Android projects at present, to good effect.
Related
I'm trying to create bindings for the android sdk provided here https://www.nmi.com/sdks-and-apis#CDNA. The binding project builds, and I can add it into my xamarin android project but as soon as I include it I get the following error/s.
error: package com.creditcall.chipdnamobile does not exist
com.creditcall.chipdnamobile.IApplicationSelectionListener ChipDnaSample.Android
C:\Users\mikee\Documents\GitHub\ChipDna\ChipDnaSample\ChipDnaSample.Android\obj\Debug\90\android\src\mono\com\creditcall\chipdnamobile\IApplicationSelectionListenerImplementor.java 8
error: package com.creditcall.chipdnamobile does not exist private
native void n_onAvailablePinPads
(com.creditcall.chipdnamobile.Parameters
p0); ChipDnaSample.Android C:\Users\mikee\Documents\GitHub\ChipDna\ChipDnaSample\ChipDnaSample.Android\obj\Debug\90\android\src\mono\com\creditcall\chipdnamobile\IAvailablePinPadsListenerImplementor.java 33
There are 64 errors of the same nature just referencing different classes. I've put all the code on GitHub here
If I go into Obj/Release/generated/src I can find IApplicationSelectionListener so it is created some binding but it doesn't actually work. Could someone point me in the right direction about what I need to do to correct errors such as these?
Thanks
You have to change the build type of the jars. The java compile can't find it, because it's not present at compile time.
Change
InputJar to EmbeddedInputJar for ChipDnaMobile.jar
ReferenceJar to EmbeddedReferenceJar for CardEaseXMLClient.jar
For more info see: https://learn.microsoft.com/en-us/xamarin/android/platform/binding-java-library/binding-a-jar
The important sentences:
Typically, you use the EmbeddedJar build action so that the .JAR is automatically packaged into the bindings library. This is the simplest option – Java bytecode in the .JAR is converted into Dex bytecode and is embedded (along with the Managed Callable Wrappers) into your APK. If you want to keep the .JAR separate from the bindings library, you can use the InputJar option; however, you must ensure that the .JAR file is available on the device that runs your app.
I'm using the commonsguy cwac-camera library, as per the demo-layout example, documented in "Working directlly with cameraview".
All is fine referencing camera/ and camera-v9/ as Android library projects in source form (I need Android 2.3 compatibility, that's what camera-v9 is for).
When I switch to using the library via JARs:
- cwac-camera-v9-0.6.8.jar only includes CameraFragment and BuildConfig classes, so I need also cwac-camera-0.6.8.jar with the other classes.
- including both JARs causes the following self-explaining error when running the project (not at compile time) Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/commonsware/cwac/camera/BuildConfig;
I could just use the source as library project, or use Gradle, but I want to know if this is a bug to open an issue on Github, or if I'm doing something wrong.
To replicate the error, just clone the demo-layout example add both .jar files to libs folder, and run the project.
No, this appears to be my fault. They must have changed something in the Gradle build process that I am using to create the JARs. I will try to fix this tomorrow. In the meantime, you could go into the cwac-camera-v9 JAR and try removing the classes in com.commonsware.cwac.camera, leaving only those classes incom.commonsware.cwac.camera.acl.
My apologies for this, and thanks for pointing it out!
I keep tests for my Android projects in four separate projects: unit and functional tests separately, and tests that require native Android environment (Activity/Service tests, functional Robotium tests) separated from tests that I suppose can safely be run in artificial environment (Robolectric + some acceptance tests for non-strictly-Android libraries). However, I need to share some utility classes between some of the projects (mostly I mean the Android Test Kit ones, but it would be nice if I could have them under Robolectric too).
How should I go about this problem? Should I create an Android library or a simple JAR with the stub android.jar as a dependency? I've tried both solutions but got strange errors like NoClassDefFoundError for classes from the support library or IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation for classes from the tested project.
This approach, "a simple JAR with the stub android.jar as a dependency", seems simpler. In your test project, besides including this JAR as a dependency, you need to check the box for this JAR in the "Order and Export" tab of "Java Build Path" in the project property if you are using Eclipse.
I am writing an Android Library Project basing on Android Bitmap class (call it AndroindLib) which contains only utility class (no activity). I tried to test it using Android JUnit, but it keeps complaining that can't find the AnroidLib.apk
What's the right way to Unit test Android Library Project?
Quoting the documentation:
"There are two recommended ways of setting up testing on code and resources in a library project:
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."
In your test project simply change the package name so that it's the same as your library's package.
For example, you have a library whose package is "com.example.lib". Create a test project targeting your library. In the manifest file you'll see package="com.example.lib.test", and targetPackage="com.example.lib". Just change the package from "com.example.lib.test" to "com.example.lib" (targetPackage leave as is).
Also, make sure that the library is referenced to your test project NOT in Java build path, but as a usual Android library : in Eclipse it must be shown as library in Project->Properties->Android tab, but not in Project->Properties->Java Build Path tab.
Then run you tests.
Per the documentation:
Testing a library module is the same as testing an app.
The main difference is that the library and its dependencies are automatically included as dependencies of the test APK. This means that the test APK includes not only its own code, but also the library's AAR and all its dependencies. Because there is no separate "app under test," the androidTest task installs (and uninstalls) only the test APK.
When merging multiple manifest files, Gradle follows the default priority order and merges the library's manifest into the test APK's main manifest.
NOTE: This solution is based on using Eclipse Indigo (3.8.2) and might have to be implemented slightly differently for another IDE although the basic principles will be the same.
I had similar issues and I found that do the following always works:
(NOTE: These instructions are for building a new project group from scratch. If you have already built parts of the project group, then you may have to modify your projects so that they connect in the same way.)
Create a new Android Library project by checking the "Is Library" checkbox during creation. (for example an Android project named "RemingtonAndroidTools").
Build the Android Library project and verify that it created a jar file in the bin folder. (for example a jar file named "RemingtonAndroidTools.jar".)
Create an empty Android Project for testing the Android app that will serve as an Android Test App. (For example an Android project named "RemingtonAndroidToolsTestApp"). You will not need to modify the source code or resources of the Android Test App project unless you have something that must be added for testing. Many things can be tested without any modifications to the Android Test App Project. The Android Test App project is a bridge between your Android Library project and the Android Junit project that makes testing of the Android Library project via Android Junit possible.
Go the Library tab of Java Build Path for the Android Test App project ("RemingtonAndroidToolsTestApp" in this example).
Add the jar file ("RemingtonAndroidTools.jar" in this example) of the Android Library Project ("RemingtonAndroidTools" in this example) via the "Add Jars..." button.
Create a new Android Test project (for example "RemingtonAndroidToolsTester") that will serve as an Android Library Tester and select the Android Test App project ("RemingtonAndroidToolsTestApp" in this example) as the target.
Go the Library tab of Java Build Path for the Android Library Tester project ("RemingtonAndroidToolsTester" in this example).
Add the jar file ("RemingtonAndroidTools.jar" in this example) of the Android Library Project ("RemingtonAndroidTools" in this example) via the "Add Jars..." button.
Find the last folder of your Android package in the Android Library Tester project ("danny.remington.remington_android_tools_test_app.test" for example) and add a test class ("MainActivityTest" for example) that inherits from ActivityInstrumentationTestCase2.
Edit the test class ("TestActivityTest" in this example) to use the activity (for example "TestActivity") of the Android Test App ("RemingtonAndroidToolsTestApp" in this example) as the parameter for ActivityInstrumentationTestCase2.
Edit the test class ("TestActivityTest" in this example) and create a default constructor that makes a call to super(Class) and passing in the class of the Android Test App ("TestActivity.class" for example).
You should end up with three projects (Android Library, Android Test App, Android Library Tester) that look similar to this:
You should end up with a class for testing your Android Library that looks similar to this:
package danny.remington.remington_android_tools_test_app.test;
import android.test.ActivityInstrumentationTestCase2;
import danny.remington.remington_android_tools_test_app.TestActivity;
/**
*
*/
public class TestActivityTest extends
ActivityInstrumentationTestCase2<TestActivity> {
public TestActivityTest() {
super(TestActivity.class);
}
}
You can then add any test that you want. You will not need to reference the Android Test App ("RemingtonAndroidToolsTestApp" in this example) further to run your tests unless they require access to an Android specific component (like the Assets folder, for example). If you need to access any Android specific components you can do so by modifying the Android Test App ("RemingtonAndroidToolsTestApp" in this example) and then referencing it via the instrumentation provided by the standard Android Junit API. (You can read more about that here: http://developer.android.com/tools/testing/testing_android.html)
If your ulitiy classes do not depend on any android specific code, you can just use standard JUnit unit tests. No need to use the Android versions.
According to this SDK guide, unit-testing a Library project can be achieved by creating a standard application project, reference the Library project and then instrument the application for unit testing.
However, when I do this and launch the test application I get the message
No tests found with test runner 'JUnit 3'.
I'm using Eclipse and the Android ADT plugin, all latest versions.
Note: the projects compile just fine. The test project also installs fine to the emulator. But in the console I can see that it looks for <library>.apk, which of course doesn't exist since I'm compiling this as a library into the test project.
Anyone got this to work? And if so, what is the trickery here?
Update: after discovering and fixing a problem, which was actually including the test classes (!), the test runner now can find all tests. But, all the tests fail with the following exceptions:
java.lang.NoClassDefFoundError: <nameOfClassInLibraryProject>
nameOfClassInLibraryProject are classes defined in the library project. These classes should be compiled into the test project, and indeed, everything compiles just fine. But when running the test project, the runtime doesn't seem to find the library classes.
After much fiddling and wasted time in Eclipse I have managed to get Android Library projects to work.
According to the Working with Library Projects article:
Instead, you must compile the library indirectly, by referencing the library from a dependent application's build path, then building that application.
The problem was that I interpreted this to mean that the library project should be added to the Projects tab in Java Build Path. Doing this makes the test project compile since the library code is obviously available to the compiler. But since the library is not compiled into a .jar or .apk in itself, the library classes are never deployed to the device.
The solution is to not add the library project to Projects, rather on the Source tab, add the library /src folder using the Link Source... button. And yes, it is the library src folder, not the library project root, that must be linked into the test project.