使用Junit进行Android单元测试:测试网络/蓝牙资源

使用Junit进行Android单元测试:测试网络/蓝牙资源,android,unit-testing,junit,mocking,stub,Android,Unit Testing,Junit,Mocking,Stub,我逐渐沉迷于单元测试。我正在尝试使用测试驱动开发来开发尽可能多的软件。我正在使用JUnit对我的android应用程序进行单元测试 我一直在开发一款使用蓝牙的应用程序,现在很难对它进行单元测试。我有一个活动,它使用BluetoothAdapter获取已配对和已发现设备的列表。虽然它可以工作,但我想知道如何对它进行单元测试 为了获得配对设备的列表,我在BluetoothAdapter实例上调用getBondedDevices()。问题是我不知道如何存根或模拟此方法(或我的活动调用的任何其他blue

我逐渐沉迷于单元测试。我正在尝试使用测试驱动开发来开发尽可能多的软件。我正在使用JUnit对我的android应用程序进行单元测试

我一直在开发一款使用蓝牙的应用程序,现在很难对它进行单元测试。我有一个活动,它使用BluetoothAdapter获取已配对和已发现设备的列表。虽然它可以工作,但我想知道如何对它进行单元测试

为了获得配对设备的列表,我在BluetoothAdapter实例上调用getBondedDevices()。问题是我不知道如何存根或模拟此方法(或我的活动调用的任何其他bluetoothAdapter方法),因此我无法根据不同的配对设备列表测试我的活动

我曾考虑过使用Mockito或尝试将BluetoothAdapter子类化,以某种方式剔除我感兴趣的方法,但它是最后一个类,所以我也不能这样做

关于如何测试使用BluetoothAdapter或其他(据我所知)难以或不可能存根或模拟的资源的程序,有什么想法吗?另一个例子是,如何测试使用套接字的程序

提前谢谢你的帮助


aleph_null

为了测试您的活动,您可以重构代码。引入带有默认实现的
BluetoothDeviceProvider

public interface BluetoothDeviceProvider {
    Set<BluetoothDevice> getBluetoothDevices();
}

public class DefaultBluetoothDeviceProvider implements BluetoothDeviceProvider {
    public Set<BluetoothDevice> getBluetoothDevices() {
        return new BluetoothAdapter.getDefaultAdapter().getBondedDevices();
    }
}
公共接口BluetoothDeviceProvider{
设置getBluetoothDevices();
}
公共类DefaultBluetoothDeviceProvider实现BluetoothDeviceProvider{
公共设置getBluetoothDevices(){
返回新的BluetoothAdapter.getDefaultAdapter().getBondedDevices();
}
}
然后在活动中注入此新接口:

public class MyActivity extends Activity {
    private BluetoothDeviceProvider bluetoothDeviceProvider;

    public MyActivity(BluetoothDeviceProvider bluetoothDeviceProvider) {
        this.bluetoothDeviceProvider = bluetoothDeviceProvider;
    }

    protected void onStart() {
        Set<BluetoothDevice> devices = bluetoothDeviceProvider.getBluetoothDevices();
        ... 
    }
    ...
}
公共类MyActivity扩展活动{
私人蓝牙设备提供商;
公共MyActivity(蓝牙设备提供器蓝牙设备提供器){
this.bluetoothDeviceProvider=bluetoothDeviceProvider;
}
受保护的void onStart(){
Set devices=bluetoothDeviceProvider.getBluetoothDevices();
... 
}
...
}
现在,该活动似乎可以进行单元测试。但是蓝牙设备仍然是最终的,你不能在你的活动中注入模拟。因此,您必须重构这段新代码,并引入一个包装BluetoothDevice的新接口…->android核心类的抽象层

最后,可以通过各种单元测试来检查活动行为。。。因此,新引入的接口的实现还有待测试。为此,您可以:

  • 保持它们不进行(单元)测试,这对我来说不是什么大问题,因为它们只是进行授权


另请查看此wiki页面。

An将有所帮助。您是否找到解决方案或解决方案的提示,或者您是否最终重构了现有代码以允许类似于下面建议的内容?@Rastikan我记不清了,但我可能使用了最新版本的Robolectric来完成此任务。现在,我的测试没有我应该做的那么多,因为Android上的单元测试支持真的很糟糕。希望在去年@aleph_null。。有什么提示吗?虽然在接口/具体类中封装类很乏味,但为了测试重要特性,可能值得这么做。谢谢你的回答。我肯定会研究PowerMock,知道它是否与Android兼容吗?我从未在Android上尝试过PowerMock,但它似乎兼容,看看我知道它是几年后的事了,但Mockito 2.+现在可以模拟最终类了……)