Search code examples
google-cloud-platformandroid-thingsgoogle-cloud-iot

Testing Google IoT Core Client for Android


An Android Things project with the following unit test fails:

import com.google.android.things.iotcore.IotCoreClient;
import org.junit.Test;

public class ExampleUnitTest {

    @Test
    public void clientTest() {
        new IotCoreClient.Builder();
    }
}

build.gradle dependencies:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    compileOnly 'com.google.android.things:androidthings:1.0'
    implementation 'com.google.android.things:cloud-iot-core:1.0.0'
    testImplementation 'com.google.android.things:cloud-iot-core:1.0.0'
}

Error output:

java.lang.VerifyError: Expecting a stackmap frame at branch target 36
Exception Details:
  Location:
    com/google/android/things/iotcore/IotCoreClient$Builder.build()Lcom/google/android/things/iotcore/IotCoreClient; @22: ifnonnull
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0000000: 2ab4 0013 1203 b800 1e2a b400 1412 06b8
    0000010: 001e 2ab4 0015 c700 0e2a bb00 0959 b700
    0000020: 1ab5 0015 2ab4 0017 c600 112a b400 16c7
    0000030: 000a 2ab8 001f b500 162a b400 19c6 0011
    0000040: 2ab4 0018 c700 0a2a b800 1fb5 0018 bb00
    0000050: 1059 2ab4 0013 b600 1b2a b400 13b6 001c
    0000060: bb00 1259 b700 23b7 0022 4ca7 000d 4cbb
    0000070: 000e 592b b700 20bf bb00 0b59 2ab4 0013
    0000080: 2ab4 0014 2b2a b400 152a b400 182a b400
    0000090: 192a b400 162a b400 1703 b700 1db0     
  Exception Handler Table:
    bci [78, 107] => handler: 110

I can instantiate the Builder just fine inside an Activity, but would like to write tests for it as well. Is there a way to test my IoT Core connection?

It might just be a dependency issue, but I'm out of ideas.


Solution

  • The library relies internally on the Paho MQTT client, which is not exposed transitively to callers as part of it's public API (i.e. the classes aren't visible through the library). The errors you are seeing occur because the IotCoreClient.Builder tries to instantiate an internal MQTT client class that the test can't see. You can find the source for the Cloud IoT Core client on GitHub.

    Aside from this specific error, I would recommend against building a test like this. It creates two concerns that you generally want to avoid in testing:

    1. As written, this looks like a test to verify whether the Cloud IoT client is working (in other words, whether Google's library code is working rather than whether your code is working). Unit tests should focus on verifying the behavior of your code and stubbing out the implementation details of any dependencies.

    2. A unit test that connects all the way to Cloud IoT is not hermetic, and therefore it's difficult to provide repeatable results. Failure modes ranging from a bad internet connection to unexpected device data can cause the test to fail incorrectly. Ideally, you would provide a mocked or stubbed interface to the test where you can provide deterministic results to the actual code under test.