Android Unit Test + DecimalFormat - android

I have a method that formats a number, and I wanted to test it.
I built a test calling this method and the result showed that: decimalFormat.setRoundingMode(\* Any rounding mode \*);
doesn't work. It always takes the default RoundingMode.HALF_EVEN.
My method works fine - decimalFormat.setRoundingMode(RoundingMode.HALF_UP); do work when running the app (I copied the test to the app and logged it..)
Why can't I call decimalFormat.setRoundingMode() in a unit test?

Please post your code. Replace the RoundingMode.HALF_UP value with its hard coded primitive value (the value behind it).The static call to RoundingMode might be the cause of this.
It also seems to me that your unit test is wrong, you're checking a behavior of a class based on an existing implementation of your dependency (decimalFormat). You should never do this in an unit test instead you have to mock decimalFormat away and test the behavior of your method independently from the implementation of 'decimalFormat' or any other dependency.

Related

How to test against different display sizes in android (espresso)?

In robolectric we can use annotations inside unit tests to test against specific display sizes/densities, like
#Config(qualifiers = "w2000dp")
My aim is that my test should only run when a specific condition is given (here: w2000dp).
I'm searching for a similar way to do this when testing with Espresso.
Currently I have two alternative (fall back) solution I could use to solve the issue, but maybe there is something more generic like in robolectric.
a) I can place a parameter inside ressource value folder (values-w1000dp, values-w2000dp).
I could read the value of that parameter (displayWidth) inside the test and decide whether to run the test or not.
values-w1000dp/strings.xml
<string name="displayWidth">1000dp</string>
values-w2000dp/strings.xml
<string name="displayWidth">2000dp</string>
b) I could read out the display size / density programmatically inside the test and decide, whether to run the test or not.
But both solutions feel wrong. Is there any other common way to solve this?

Android Easymock, how to add one more expectation without resetting the mock

I've added expectation for a method like this,
expect(locationManager.isLocationSettingsEnabled(anyObject(FragmentActivity.class))).andReturn(isLocationEnabled).anyTimes();
replay(locationManager);
But when I add, expectation for one more method(mentioned below) after replay, the first method is reset automatically.
expect(locationManager.isNotificationSettingsEnabled(anyObject(FragmentActivity.class))).andReturn(isNotificationsEnabled).anyTimes();
I would like to know how to add one more expectation without resetting it.
Easymock functions on this principle.
When You set some expectations on method, you are typically faking/mocking the behaviour of that method.
Now when you call replay(mockObject), Easymock injects this mocked behaviour in Test Runner environment.
Therefore, you need to do all the expectations on a mocked object before you replay the mocked object.
something like this:
EasyMock.expect(mockObject.method1()).andReturn(null);
EasyMock.expect(mockObject.method2()).andReturn(null);
EasyMock.replay(mockObject);
Looking closely at your Question, I see that You are mocking a single method with two different return clauses
you can do something like this :
EasyMock.expect(mockObject.method1()).andReturn(new Integer(1)).once();
EasyMock.expect(mockObject.method1()).andReturn(new Integer(2)).once();
EasyMock.replay(mockObject);
by this Easymock will return 1 as output for first time when method is invoked and 2 when method is invoked for second time.
Hope this Helps!
Good luck!

Avoid a block of code to run during unit test using mokito

I am using Mokitio in android to run unit test cases.
.
What i am trying to do: There is a block of code in onCreate event
of the activity
I am trying not to run this block of code during Running Unit test
cases and run it during app regularly.
Is it possible to do something like that using mokito because mokito synchronizes for activity life cycle
The proper solution here is to change your design a bit. You should not think in terms of code blocks, but in terms of functionality.
The way of preventing that some x lines of code are run in a certain environment, but are not in some other context ... is by using proper OO means.
Meaning: first create an interface that describes the functionality of those lines of code we are talking about:
public interface DoTheFoo {
public void foo(Bar bar);
}
Then you create a "production" implementation DoTheFooImpl of that interface (which as a side effect: you might be able to write proper unit tests for as well).
Finally: within your class that needs that functionality, use dependency injection to acquire an object providing the DoTheFoo interface. In your production environment, that would be a DoTheFooImpl object; but for your unit testing, you would simply create an mock for it - configured to do nothing upen calls to foo().
Of course that sounds like a bit of work; but the point is: currently, your design is somehow deficient. And instead of trying to go for dirty hacks/workarounds, consider looking at your design to identify a more elegant way to resolve your problem.

Calling findViewById() in Junit test

I an new to unit testing and I have a simple test method that isnt working. Here is what I have:
#Test
public void testLayoutAvailable() {
View v = mMainActivity.findViewById(R.layout.main_activity);
assertNotNull(v);
}
My problem is v is always null. I stepped through the code and mMainActivity is not null and the rest of my test methods all work fine. So I'm sure there is something simple that I'm just not aware of yet. I checked my imports and I also tried com.packagename.R.layout.main_activity and that also returns null. However the app its self works fine, so I know the layout is there and this test should pass.
Any suggestions?????
When you run normal JUnit tests on Android, the rest of the application isn't fully constructed.
However Android provides some helper classes which construct enough of the application such that you are able to test it. Take a look at http://developer.android.com/tools/testing/activity_testing.html
I have mostly used ActivityInstrumentationTestCase2 in the past.
I found out the problem was I was passing in a layout not an id to findViewById().

better way to do Debug only assert code

I am writing my first Android application and I am liberally using asserts() from junit.framework.Assert
I would like to find a way to ensure that the asserts are only compiled into the debug build, not in the release build.
I know how to query the android:debuggable attribute from the manifest so I could create a variable and accomplish this in the following fashon:
static final boolean mDebug = ...
if (mDebug)
Assert.assertNotNull(view);
Is there a better way to do this? i.e. I would prefer not to use an if() with each assert.
thanks
I think the Java language's assert keyword is likely what you want. Under the covers, the assert keyword essentially compiles into Dalvik byte code that does two things:
Checks whether the static variable assertionsDisabled (set in the class' static constructor via a call to java.lang.Class.desiredAssertionStatus()) is != 0 and if so, does nothing
If it is 0, then it checks the assertion expression and throws a java.lang.AssertionError if the expression resolves to false, effectively terminating your application.
The Dalvik runtime by default has assertions turned off, and therefore desiredAssertionStatus always returns 1 (or more precisely, some non-zero value). This is akin to running in "retail" mode. In order to turn on "debug" mode, you can run the following command against the emulator or the device:
adb shell setprop debug.assert 1
and this should do the trick (should work on the emulator or any rooted debugging-ready device).
Note however that the aforementioned Dalvik code that checks the value of assertionsDisabled and throws an AssertionError if the expression is false is always included in your byte code and liberal sprinkling of asserts in your code may lead to byte code bloat.
Please see this for a bit more detail: Can I use assert on Android devices?
If you're concerned about shipping code with the JUnit asserts in (or any other class path), you can use the ProGuard config option 'assumenosideeffects', which will strip out a class path on the assumption that removing it does nothing to the code.
Eg.
-assumenosideeffects class junit.framework.Assert {
*;
}
I have a common debug library I put all my testing methods in, and then use this option to strip it from my released apps.
This also removes the hard to spot problem of strings being manipulated that are never used in release code. For example if you write a debug log method, and in that method you check for debug mode before logging the string, you are still constructing the string, allocating memory, calling the method, but then opting to do nothing. Stripping the class out then removes the calls entirely, meaning as long as your string is constructed inside the method call, it goes away as well.
Make sure it is genuinely safe to just strip the lines out however, as it is done with no checking on ProGuard's part. Removing any void returning method will be fine, however if you are taking any return values from whatever you are removing, make sure you aren't using them for actual operational logic.
I mean if you were using a language feature, like assert(), the compiler should be able to strip that out. But this is an actual class and if a class is referenced by executable code it will be included or assumed included in the final product by the compiler.
However there is nothing stopping you from creating a script that removes all the references to the Assert class in all of your code base before compilation.
Another approach would be to make a test project that targets your application and within JUnit tests actually calls the Assert on the areas which you want to make sure work. I personally like this approach because it is a nice and clean separation of test and application.
If you are just worried about the having an if-statement everywhere, then just wrap Assert with your own class, DebuggableAssert which does that check before each call to Assert.X. It will be sort of less performant because of the method entry/exit and the conditionals but if you can maintain your code better then it might be worth it.

Categories

Resources