Mocking framework for use with xamarin android - android

I am trying to find a mocking framework that works with Xamarin Android. So far I have tried Rhino Mocks and Moq but both depend on System.Web.dll which does not seem to be supported by Xamarin. I have included the System.Web.Services reference to my project with no luck.
So my question is what mocking frameworks out there are compatible with Xamarin projects? This is just for simple mocking not even specific android classes like activities, although one that could combine both would be best.

From what I've observed, there really is no mocking frameworks that work well with Xamarin. On the iOS side, this is mainly due to the inability to use Reflection.Emit because of the code generation restriction imposed by Apple. I realize you're on Android, so that restriction does not apply to you. However, other restrictions arise, like you've found with RhinoMocks. My favorite mocking framework is Moq, but I can't use it with Xamarin because of some of the configuration namespaces that are implemented in .NET, but not in Mono.
So, your best bet is just manual mocks. I know that's not the answer you want to hear, but it seems to be the consensus.

You can use True Fakes (http://truefakes.net) mocking framework to solve your issues. It doesn’t use Reflection.Emit at runtime, but it automatically generates mocks at compile time and add it to assembly where unit-tests are. This allows you to use True Fakes for writing unit tests with fully isolated system under test for Xamarin.Android and Xamarin.iOS and running them directly on the device!
You can add it to your project via NuGet (https://www.nuget.org/packages/TrueFakes/).
Please see more information about True Fakes at http://truefakes.net.
PS. I’m developer of True Fakes mocking framework.

I've been using a mock generator called PCLMock.
I had to fork it to get it working with .netstandard, you can give it a go by cloning it and building it from here:
https://github.com/pellet/PCLMock
It works by generating code before compile time, therefore not needing the reflection apis missing in AOT compiled xamarin projects.
Otherwise you could always go functional style and pass in your dependencies as delegates/Funcs, this way you don't need to generate mocks for interfaces, you can use a builder class for injecting mocked out lambdas in unit tests.

Related

Test Driven Development For Android

Can we use JUnit for test driven development in Android ? If not, is there an alternative similar to JUnit ?
I searched a bit on google and also read a SO post Android Test Driven Development
It looks like Android was never made with TDD in mind. I wanted to be sure before I begin learning TDD and doing Android development at the same time.
I think you can completely rely on Robolectric for running your tests in JVM. You get to use JUnit4 for testing your POJOs and Robolectric provides you the support for testing the Android components.
I am also a beginner in TDD for Android Development. I find Robolectric really useful for test driving my code.
This video will tell you almost everything it provides you for unit testing the Android code.
UPDATE:
With the Android studio support and the new Android ecosystem, now unit testing can be done as a first class practice. Refer http://developer.android.com/training/testing/unit-testing/local-unit-tests.html for more details.
There are couple of good approaches to test drive the android code. The most effective ones I have found so far is using MVVM(model-view-viewmodel) or MVP(model-view-presenter) approach, where the business logic as well as presentation logic is decoupled from the view and can be easily be unit tested.
Yeah we can use JUnit for test driven development. To initiate with you can refer to following
link : http://developer.android.com/tools/testing/testing_android.html#JUnit
Following the documentation we can use the junit.framework to have unit testing done.
Here is a bit of explanation of the problem space: http://www.techwell.com/2013/04/applying-test-driven-development-android-development
The conclusion is you should use Robolectric. Unfortunately Robolectric is slow, and if you follow TDD even on a pragmatic level, you will end up with a couple of hundreds of test, that will run for couple of 10 seconds. And that is not you want to do with TDD. TDD test package should run at most in seconds.
My advise is:
Create wrapper classes around Android classes that simply call the Android class.
Write your app logic in pure Java.
Use Junit (or TestNG or whatever pleases you) to test you model/business logic
Use occasionally Robolectric for the wrapper classes (probably you won't have to use)
(You can write integration tests that use multiple classes, Robolectric, etc. but only run it on a separate Continous Integration server eg. hourly)
With this approach your logic will be more portable as well.

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

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?

Is it possible to create a stub of android.os.Bundle for testing under JVM?

As the title says, I want to know, if possible, how can I create a stub from Bundle to run at JVM (so not Dalvik). Since its part of android.os package, may be that is related to that impossibility.
My point is due to the fact that I want to use a mocking framework, which run at JVM, to test the Activity.onCreate() method.
I've already found this link but it seems they use a stripped custom android.jar since its rather experimental and unproven (yet I could not reproduce even with their jar, maybe I need some sleep).
If there is another alternative to mock testing this, any insights will as always be appreciated.
Thanks.
I've been successfully writing unit tests on the java jvm for classes that interact with android.jar classes. I use Powermock to mock out all android classes (like Bundle).
This link talks about using a version of the android jar that does not throw the "stub" exception on the java jvm. I have not needed to use a different version of the android jar. Using Powermock I've been able to successfully mock out anything I need to. For me this unit testing technique is not experimental.
Having said that - the unit tests for classes that extend activities, fragments, etc. become very much mock heavy. I feel it's good to move as much logic as you can into pojo classes, keeping your android extended classes as thin as possible. You can decide then if you feel it's worth isolation junit testing the android extended classes. It can certainly be done if you wish. You can also consider an integration testing framework like the one provided by Android or Robotium to test your android extended classes and their lifecycles.

Mocking library/framework that works best in Android? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'm developing Android application using third party libraries (Twitter4j). I want to be able mock those objects (also objects created by me) in JUnit and functional tests.
Do you have any good experiences using some mocking libraries and you can recommend them?
(Update: Mockito has added Android support as of version 1.9.5 and EasyMock has added Android support as of version 3.2 by factoring out those bits that generate code at runtime and making them pluggable, e.g. by using dexmaker instead of cglib.)
Except for android-mock mentioned by DixonD (which is a fairly young, unproven library), there currently is no solution. You can immediately forget anything based on CGLib (Mockito, plain EasyMock), since CGLib relies on byte code generation and won't work on Dalvik (it also relies on the Java Beans package, which is also not part of Android).
For what it's worth, you could use the very few mock classes coming with Android (like MockContext), but they don't verify behavior, they're just stubs. Their default behavior is to throw a runtime error in every method, so you have to subclass them and override the methods you want to mock.
However, you can still use mocking libraries in non-instrumentation tests, i.e. in your standard unit tests executed on the JVM. You can use PowerMock to mock framework methods, it has support for mocking static methods and constructors, making the mocking as powerful as e.g. in Ruby (just more painful to use).
We use JUnit 4 + PowerMock + Mockito and mock out classes like Context and TextUtils in a base class from which we inherit every normal JUnit test. For instrumentation tests, we create custom mock classes and decide using a factory which implementation (mock or not) to instantiate at runtime.
I recently released Borachio, a native Scala mocking framework which works on Android.
Because Borachio is written in Scala, you’ll need to write your tests in Scala. But it can be used to test code written in Java.
There's a description of how to use Borachio on Android on my blog:
http://www.paulbutcher.com/2011/03/mock-objects-on-android-with-borachio-part-1/
http://www.paulbutcher.com/2011/03/mock-objects-on-android-with-borachio-part-2/
http://www.paulbutcher.com/2011/03/mock-objects-on-android-with-borachio-part-3/
UPDATE:
Borachio now is ScalaMock.
Robolectric uses a different approach. Instead of running on the DVM, it "defangs" the Android SDK so that you can run Android tests directly on the JVM with the JUnit4 framework. Tests apparently build and run much faster, and require less mocking.
[A common approach] is to use mock frameworks such as
Mockito or Android Mock to mock out the Android SDK. While this is a
valid approach, we have found that without Robolectric, the level of
mocking needed to test an Android app quickly yields tests that are
essentially reverse implementations of the application code.
Robolectric allows a test style that is closer to black box testing,
making the tests more effective for refactoring and allowing the tests
to focus on the behavior of the application instead of the
implementation of Android. You can still use a mocking framework along
with Robolectric if you like.
Here's how it works:
[It intercepts] the loading of the
Android classes and rewriting the method bodies. Robolectric
re-defines Android methods so they return null (or 0, false, etc.), or
if provided Robolectric will forward method calls to shadow Android
objects giving the Android SDK behavior.
A comparison to Mockito.
Android Mock is written on top of EasyMock 2.4 which is well-known mock framework for Java
Lmock is working on Android : github.com/vmware/lmock
update: looks like easymock 3.2 added an option for plugging-in alternatives for cglib.
I'm using easymock 2.5.2 (note - do not use 3.X). it works - but only for mocking interfaces.
Thus if your library exposes interfaces or if you're willing to wrap our dependencies with interfaces you can use easymock.
Later easymock versions such as easymock 3.x won't work because they use the android-incompatible cglib for bytecode manipulation for both classes and interfaces while 2.x uses it only for mocking classes.
I have just tried Android-Mock. It works very well so far. It Resolved my issue (either use AndroidTestCase without EasyMock, or use EasyMock but no context allowed)

Categories

Resources