Mockito UnfinishedStubbingException in tests

Ever wonder why Mockito will occasionally give you an UnfinishedStubbingException even though you clearly finished the stubbing?

For example, the following code will fail at runtime (mockChannel has been setup earlier):

1
2
whenever(mockChannelNameProvider.nameForChannel(mockChannel))
    .thenReturn(mockChannel.id())

With an exception like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at ExampleFailingTestKotlin.setupChannelName(ExampleInterfacesTest.kt:30)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed

This is a very good exception message. It gives you some common examples of what you might have done wrong, and how to fix them. However, our code doesn’t match any of the examples.

Read on →

Asynchronously loading data using Googles Paging Library

The recently released Paging Library from Google gives you an easy way to page data into memory off of the main thread. If you want to use it with Room, then the built-in support makes it trivial. However, if you’d like to page data that exists elsewhere - from the network or disk, for example - then you have to do a little extra work.

Here I demonstrate how to take existing code that loads a list of screenshots from disk and convert it to load asynchronously using the Paging Library. This example could easily be adapted for network calls.

Read on →

Tensorflow in Windows Bash

My first job out of university was at a startup doing natural language processing (NLP). Recently I’ve been rekindling my interest in machine learning, and have been playing with the Tensorflow library from Google. I work on a Mac, but at home I’m switching between a Mac and a PC - and ideally I’d like things to just work on whatever machine I’m on. The Tensorflow setup guide says it requires Python 3.5 for Windows, but I’m using Python 2.7 on my Mac and would like to be able to use files across platforms.

Here’s a quick intro to getting set up with Tensorflow for Python 2.7 on Windows (using the recently released Bash on Windows).

Read on →

Implementing GCM Network Manager for periodic network requests on Android

In the process of rebuilding What’s Shaking, NZ?, I needed to implement a periodic network request (literally polling an API). I wanted to use the new Job Scheduler API, but unfortunately, this is only available on API 21 and above. Luckily we can get similar functionality by using GCM Network Manager, as suggested on StackOverflow. Note that the GCM Network Manager actually uses Job Scheduler behind the scenes in API 21+.

The documentation for this is somewhat hand-wavy. Here I attempt to provide a true step-by-step guide to implementing this. I assume you’re not already using GCM for something else in your app (as that was the case for me).

Read on →

Handling RealmMigrationNeededException on a fresh installation on Android

Back in November, I had just started using Realm on Android and was having some troubles. I’d occasionally need to make a model change, and being early on in development I was happy to just delete the Realm and start again - in production you’d want to perform a migration so you don’t lose any user data.

However, the “delete and re-install” approach wasn’t working as expected - I kept getting a RealmMigrationNeededException:

1
io.realm.exceptions.RealmMigrationNeededException: RealmMigration must be provided

This doesn’t make sense! I should be able to uninstall an app and upon reinstalling it I should have a fresh slate to work with. As it turns out, not quite. I couldn’t figure out why at the time, but the workaround was to simply add a deleteRealmMigrationIfNeeded() call to my Realm configuration when building it. I made a note to deal with this before release, and carried on my way.

Read on →

Automating iOS build numbers

I recently encountered some problems where I was accidentallly duplicating build numbers for our iOS app. At Bridgit we’re big fans of automation, so I went about finding a way to avoid this human error and let the machines do the work for me.

Read on →

A bug in (and a fix for) the way FragmentStatePagerAdapter handles fragment restoration

Ever used a FragmentStatePagerAdapter? We’re using one at work for our ticket purchasing wizard. The user enters the wizard, and can progress to the next page once they’ve completed the current one. We control this by manipulating the stack of pages and notifying the adapter that the data has changed when a new page is available.

Unfortunately, when changing pages that have already been loaded, there’s an unexpected bug. Specifically, when you load a page, remove it and then insert a new one in its place, the next time the fragment at that index is loaded, it receives the savedInstanceState bundle for the old fragment.

Read on →

Broken JSONObject creation from a UTF-8 input String

12-16 12:01:40.446: W/System.err(3873): org.json.JSONException: Value  of type java.lang.String cannot be converted to JSONObject

Faced this issue, again, at work today. We have a build system with build variants for different customers. To add a new customer, we just create a new folder, add the images and add a JSON config file to suit the new customers settings. We read from that file and into a JSON string (and then into a JSON object) something like this:

1
2
3
InputStream inStream = context.getResources().openRawResource(R.raw.local_config);
String json = IOUtils.toString(inStream);
JSONObject jsonObject = new JSONObject(json);

Sometimes, new customers speak a language other than English, and we have to save non-ASCII characters. In this case, the file gets saved as UTF-8. Testing this isn’t a problem on my devices (Galaxy S2/Nexus 7) - but my tester has twice come back to me now and said that it doesn’t work on our 2.3 device.

Read on →

Getting started with Volley for Android

Volley is a new Android networking library from Google (well, by ‘new’ I mean from May, at I/O 2013 - so some 7 months ago). It has some cool features - request queueing with priorities, automatic selection of the best HTTP library depending on Android version, and a nifty view for automatically loading images. Unfortunately, even 7 months on, there’s pretty minimal documentation available. However across StackOverflow, a bunch of blogs and the source code, there’s plenty to go on to figure out how to do some basic tasks.

Read on →

Handling OutOfMemoryError with large bitmaps on older Android devices

If you’ve ever worked with bitmaps on an Android device before, you’ve likely encountered the dreaded OutOfMemoryError ‘bitmap size exceeds VM budget’. This issue can present itself immediately when testing, however on older devices it may not manifest except in certain cases. The reason for this is as follows:

In addition, prior to Android 3.0 (API Level 11), the backing data of a bitmap was stored in native memory which is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash.

Depending on what you’re doing, there is a way to get around this.

Read on →