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

ale*_*ull 16 junit android unit-testing mocking stub

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

我一直在研究一个使用蓝牙的应用程序,并且我正在进行单元测试.我有一个Activity,它使用BluetoothAdapter获取已配对和已发现设备的列表.虽然它有效,但我想知道如何进行单元测试.

要获取配对设备列表,我在BluetoothAdapter实例上调用getBondedDevices().问题是我不知道如何存根或模拟这个方法(或我的Activity调用的任何其他bluetoothAdapter方法)所以我无法针对不同的配对设备列表测试我的Activity.

我想过使用Mockito或尝试将BluetoothAdapter子类化以某种方式存在我感兴趣的方法,但它是最终的类,所以我也做不到.

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

提前感谢您的帮助

aleph_null

gon*_*ard 5

要测试您的活动,您可以重构您的代码.介绍一个BluetoothDeviceProvider默认实现.

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

public class DefaultBluetoothDeviceProvider implements BluetoothDeviceProvider {
    public Set<BluetoothDevice> getBluetoothDevices() {
        return new BluetoothAdapter.getDefaultAdapter().getBondedDevices();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在活动中注入这个新界面:

public class MyActivity extends Activity {
    private BluetoothDeviceProvider bluetoothDeviceProvider;

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

    protected void onStart() {
        Set<BluetoothDevice> devices = bluetoothDeviceProvider.getBluetoothDevices();
        ... 
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在这项活动似乎可以进行单元测试.但是BluetoothDevice仍然是最终的,你不能在你的活动中注入模拟.所以你必须重构这个新代码并引入一个新的界面来包装BluetoothDevice ... - >核心android类的抽象层.

最后,可以通过各种单元测试来检查活动行为......所以新引入的接口的实现仍然需要测试.为此,您可以:

  • 让他们不(单位)测试,对我来说不是一个大问题,因为他们只是做代表团

  • 看看PowerMock.

另请查看此Wiki页面,了解如何使用PowerMock模拟最终类.

  • 尽管将类包装在接口/具体类中很繁琐,但为测试重要功能可能值得这样做。感谢您的回答。我一定会研究PowerMock,是否知道它是否与Android兼容? (2认同)