Getting Started (Sweetunit)

With the unit test module for SweetBlue, it allows you to unit test your application using SweetBlue. All Bluetooth operations are mocked and provide best-case use out-of-the box. All operations can also be overriden to provide failure cases as well. The library requires robolectric to mock out the needed Context (you can use Mockito, or another mock library, but they are not tested, and require more work).

  • Modify your app's build.gradle file to pull SweetBlue down from our maven server, and add the dependency to your project, and to allow unit tests to have access to the app's resources (so it can read the API key in the assets folder):


android {
    ...
    testOptions {
        unitTests.includeAndroidResources = true
    }
    ...
}

repositories { ... maven { url "https://archiva.sweetblue.io/repository/internal" } }

dependencies { ... implementation "com.idevicesinc:sweetblue:3.0.2" // Make sure to only include the dependency on the test variant testImplementation "com.idevicesinc:sweetunit:3.0.2" // Robolectric is used to mock an Activity instance. It's possible to use another library for this such as Mockito, // but it's untested, and would require more work. testImplementation "org.robolectric:robolectric:3.8" }

Sample Unit Test

// If you wish to mock certain SDK versions, you can set them with the Config annotation
@Config(sdk = 25)
@RunWith(RobolectricTestRunner.class)
public class MyTestClass {

    private final static UUID myServiceUuid = Uuids.fromShort("AB01");
    private final static UUID muCharUuid = Uuids.fromShort("AB02");

    private Activity m_activity;
    private BleManager m_manager;

    // Create a database so there is something to write to
    private GattDatabase m_db = new GattDatabase().addService(myServiceUuid)
                                     .addCharacteristic(myCharUuid).
                                     setProperties().readWrite().
                                     setPermissions().readWrite().completeService();

    // This method runs before every test in this class. It sets up the BleManager for 
    // you, so you can just start using it in your test method.
    @Before
    public void setup()
    {
        // Just using base Activity class here, but you can use whatever Activity you 
        // want here
        m_activity = Robolectric.setupActivity(Activity.class);
        // Now create our BleManager instance
        BleManagerConfig config = new BleManagerConfig_UnitTest(m_db);
        m_manager = BleManager.get(m_activity, config);
    }

    // It's a good idea to make sure to tear down the BleManager after every test, and
    // this method allows you to do that (it's really the @After annotation)
    @After
    public void shutdown()
    {
        m_manager.shutdown();
        m_activity = null;
    }

    @Test
    public void simpleWriteAndReadTest() throws Exception
    {
        // As most of SweetBlue's actions are asynchronous, we need a semaphore to 
        // hold onto this thread, and release it when we are done with the test.
        final Semaphore semaphore = new Semaphore(0);

        final BleDevice device = m_mgr.newDevice(Util_Unit.randomMacAddress(), "MyTestDevice");

        final byte[] myData = new byte[] { 0x9, 0xB, 0x44, 0x16, 0x2, 0x7A, 0x3F };

        device.connect(e ->
        {
            assertTrue(e.wasSuccess());
            BleWrite write = new BleWrite(myServiceUuid, myCharUuid).setBytes(myData).setReadWriteListener(r ->
            {
                assertNotNull(r.data());
                BleRead read = new BleRead(myCharUuid).setReadWriteListener(readEvent ->
                {
                    assertArrayEquals(myData, readEvent.data());
                    semaphore.release();
                });
                device.read(read);
            });
            device.write(write);
        });

        semaphore.acquire();
    }


}