Android JUnit Test: have some skipped internal methods - android

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 :-)

Related

Robotium with Mockito or Easy Mock

I'm new to Android testing and I`d really appreciate if some of you could help me with that.
I'm using robotium as automation testing framework (so far so good), but I have no idea how I use mockito or Easy Mock to add some mocks to my tests. I'm really stuck with that. Can someone give me some simple example on how to achieve this?
Thanks in advance
Short Answer/opinion
I don't recommend using Mockito for Android unit testing. The Android environment feels too complex to mock. The basic approach for Android unit tests is to run them within the emulator. Thus many of the container classes are already present and need not be mocked.
Long Answer
I also am relatively new to the world of Android unit testing. I have long written server-side unit tests and found Mockito to be one of the best tools around to simplify unit testing. Mockito is very helpful in mocking the behavior of complex objects. This helps to break any dependencies that your code-under-test may have on containers (e.g. servlet container or OSGI container), or on other complex collaborators (e.g. database connection classes).
This sort of mocking works well when your containers/collaborators have well-defined interfaces.
A couple months back, I decided to try Mockito with Android development. I found that Mockito does work if you have at least 1.9.5 and dexmaker. Dexmaker handles runtime byte-code generation for Android's Dalvik VM.
The first thing I tried in my very first test was to mock android.content.Context, and I found that is was HARD. First I tried to mock only the methods that I called directly, but then I found that these called into other methods which had dependencies on application resources, ... Eventually the mocking got so complicated that it defeated the purpose of using Mockito in the first place.
So I gave in and started using the Android unit test helper classes (AndroidTestCase, ActivityUnitTestCase, ...). I was discouraged that I now had to rely on the emulator which meant SLOW test execution. Perhaps Mockito still has a place in this type of test. It might be useful for mocking things like external data sources.
Anyways, this is just my 2 cents.

Using JUnit on android project by mocking few android api classes?

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

AndroidAnnotations and Unit Testing

I am using AndroidAnnotations(2.5) in a sample project I am currently working on.
Since you can annotate your classes with for example #EActivity,#ViewById,#Click which will all lead to generated compile-time code, I was wondering how one would go about creating unit tests / functional tests for any Android Annotations powered application.
I would love to hear some opinions on this matter.
Cheers,
I responded to a similar post here.
There are a couple of options available to you. You can, of course, test your code pre-generation in, what I claim, is a more unit testing style. This should test the Java code in isolation, preferably without generated code involved.
You can also test the code post-generation. The MyActivity_ classes generated by AA can be instantiated directly after compile time and test them accordingly. I claim this is edging towards an integration testing style.
While, I think it is always better to test than not to test, I think for integration tests, you should test on the hardware in a situation similar to production. This gives you a total picture of how your application will behave in a real world situation. Thus, for integration tests I prefer high level "is everything working well together" tests.
Robolectric and Robotium can help greatly in these two efforts. Robolectric allows you to instantiate you Activities in a unit test, while Robotium allows you to test selenium style directly on a device.
To recap, I prefer to heavily unit test my code without generation then do some light integration testing to make sure everything is working well together.

Testing Android code with JUnit and the JDK

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?

jUnit testing Database operations

I'm developing an Android application with database storage.
I want to test some classes that I use to access database.
I've found ActivityInstrumentationTestCase2 to test Activities but I haven't found anything to test classes.
How can I do that? I haven't used jUnit before.
Thanks.
I always use AndroidTestCases when writing unit tests for the Android platform. They provide access to a Context instance (if required), but otherwise work like the standard JUnit test class. You may also need to look at AndroidTestRunner to test your classes. There are some good tutorials out there; now that you know what to look for, I'm sure you can find them. Happy hunting! :D

Categories

Resources