I am getting started with using Robolectric for testing my android app. A bit of context, my app is already built and the repo is fairly large.
I setup my IDE as instructed in the Robolectric documentation here. But trying to run the tests, I ended up with errors in my application class.
It complains that some or the other dependency is missing or running into weird states which I can't explain.(Not a great start I guess).
Is there a way, I can basically mock the application class or have a dummy application class ?
I tried to find examples but it's not clear, where I am supposed to specify the class.
Any help is much appreciated.
Related
Up and running with android, and at the same time trying to understand what I am doing.
I have tried all sorts, read as much resources as I can related to unit testing android. One way or another I still come short and error after error when I run the unit tests.
Instrumented testing was straight forward and I actually managed to satisfactory getting it working.
Now onto unit test and I have gotten tired of changing one dependency to another because one is not compatible with the version of android. Finding these dependencies is a bit of sweat, I have relied more on this forum than the docs to figure out how to piece things together.
Here is my dependency configuration:
Here is my MainActivity class
And here is my test class set up against the activity. It is fairly simple for practical purposes:
I get this error now, after resolving a bunch of other errors:
I am basically spending an awful lot of time on configuration than doing what I need to do - write the unit test.
How can I go about successfully configuring the dependencies to enable me to write a successful unit test. If my tests are also wrong, how can I correctly change them?
I started looking into the Android JUnit Testing, done some researches on the Internet, and enough trials on Eclipse with ADT.
i notice if a test case (i.e. an user-defined method in the junit.framework.TestCase subclass, or specifically, my subclass entends android.test.ActivityInstrumentationTestCase2<T extends android.app.Activity>, according to the guide in the tutorial) is non-public (no matter private or /*package*/), JUnit will give me some errors.
So, how can i have some non-test-case (internal) methods in the Android JUnit testing?
i need those methods for me to help testing the test cases.
As i found from the Internet, Android Junit test is a bit different from the original JUnit test, as some annotations like #Before and #After are not supported in Android. But i guess the way of including non-test-case methods are still the same.
Note: Please noted that i am not going to test some private methods in a class, as many people have been asking.
Thanks for any helps :-)
I have some sourcecode in my android project that just uses plain java code.
I created UnitTests (JUnit) for this classes to test them.
The problem is that the functions use internally some android classes yet.
These are Log and Base64 at the moment.
Now I am looking for a simple way to mock this Classes but I was not able to do so.
I googled and found a lot of mocking tools like jmocking, mockito, robolectric and so on, but I am very confused with this libraries and did not get one of them to work.
I did not find one good step by step tutorial that shows me how to simply mock some android class so I do not get this stub / classnotfound errors.
Questions would be:
What is the most common used android mocking library?
How do I mock some Class that I do not use directly in my UnitTest, but that are used by the functions I call?
Thanks,
Subby
I'm not sure that any mocking library will fully support Android. There are several technical reasons why Android and mocks don't get along.
If you want to unit test a java object that uses the Android API, you usually have to use one of the test case classes in android.test.*. Android classes often need an Android context in order to work correctly.
For a unit test, you usually inject a dependency, but there are limits. After all, you don't unit test the multiplication operation! You can unit test the Android classes, and once you're satisfied they're working, you can assume that they're working correctly.
You'll need robolectric to mock Android classes: http://pivotal.github.com/robolectric/index.html
I'm writing some POJO tests for my Android code.
I want to run them locally with the JDK (not with Dalvik on the emulator) - for speed, JUnit 4, Mockito, and being able to run headless without a device - so I have a separate "Java" project in Eclipse.
If the method I'm testing happens to reference anything from the Android SDK, e.g. android.util.Log, the test fails - this makes sense because android.jar isn't in the classpath. To reproduce I have this test case:
public class FooTests {
#Test
public void testFoo() {
android.util.Log.d("x", "y");
}
}
If I add android.jar explicitly to the test project's classpath, I get exceptions like
java.lang.RuntimeException: Stub!
at android.util.Log.d(Log.java:7)
at com.example.FooTests.testFoo(FooTests.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Is there a way to make the code work without mocking out every last bit of Android SDK dependency? Perhaps a mocked-out android.jar already exists?
EDIT: For now I ended up wrapping classes like android.util.Log and injecting them into the instances, for classic IOC-based testing. Scott's PowerMock suggestion is my next step when I'll need it.
LATER EDIT: Robolectric!
I had the same problem. I wanted to test simple POJOs locally.
Specifically, my code wanted to use android.util.Base64.
What I ended up doing was to use the SDK to install the Android 4 sources, and copied the android.util.Base64 class to my project.
Surprisingly enough, this worked.
There's no mocked out android.jar that I know of. I use Powermock to mock everything out. One thing you can do to help with the heavy mocking is to make your extended android classes like activity, fragments, broadcasters, etc. thin and have them delegate to pojo classes. You could make a risk based decision not to isolation unit test the android extended classes, and instead integration unit test them via the android testing framework or something else like Robotium.
For true isolation unit testing in Android, for me unit testing on the java jvm mocking all out all collaborating classes is the best way to go.
I had the same problem. I wanted to test simple business logic locally.
Specifically, my code uses android.util.SparseArray<E>.
I tried 3 different approaches to make it testable with junit outside android.
In my business logic I created an interface and attached it to MySparseArray<E> that inherits from SparseArray<E>. In the junit-test I re-implemented the interface using HashMap<Integer, E>. This works but in the long run this is to much work to make business logic unit-testable if other android.* are required.
As suggested by #Tal Weiss I added the android java sources of the required classes: android.util.SparseArray.java that uses com.android.internal.util.ArrayUtils.java. This works, too but I don't like to add more android sources, especially if there are much more dependencies
I downloaded a stub free binary android.jar for an old android 2.2 from http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1 and included it as lib into my junit-java-project. This jar contains only classes for namespaces android.*, com.android.*, dalvik.* and framework.base.*. This works too.
Currently I succeeded to avoid using android.* classes except SparseArray<E> in my business layer and has no dependency to Context, Activity or Service. I could have used HashMap<Integer, E> in the android-business layer instead of SparseArray<E>.
unmock-plugin could help https://github.com/bjoernQ/unmock-plugin. In my case it works with SparseArray.
Won't the embedded android/junit tests do what you want?
I have a project with many classes and activities. I would like to test some of those classes by creating another project and using them. Is this possible? I tried creating an Android test project in Eclipse, linking to the project I want to test, creating an activity and there using some of those classes. Unfortunately, I get NoClassDefFoundError. Could you please address me to the right direction on how to create this kind of test?
Thanks!
What you are looking for is JUnit testing. There is plenty out there to get you started.
To test activities you can fire intents using ActivityInstrumentationTestCase2