Mockito 测试检查是否启用了蓝牙

Mockito test check if bluetooth is enabled

我正在尝试学习 Mockito 和 TDD。

我有演示者使用方法:

  @Override
    public void startScanning() {
        if (isLocationPermissionGranted() && isBluetoothEnabled()) {
            mPresenterView.onStartScanBtnClick();
        } else if (!isBluetoothEnabled()) {
            mPresenterView.displayDialogRequestingBluetooth();
        } else if (!isLocationPermissionGranted()) {
            mPresenterView.displayDialogRequestingPermission();
        }
    }

    @Override
    public boolean isLocationPermissionGranted() {
        return false;
    }

    @Override
    public boolean isBluetoothEnabled() {
        return false;
    }

问题是我如何使用 Mockito Roboelectric 或 w/e.

在底部测试 2 种方法
 @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mScanningPresenter = new ScanningPresenter(mView);

        mockBluetoothAdapter = PowerMockito.mock(BluetoothAdapter.class);
    }



  @Test
    public void shouldPassPowerMock() {

        assertEquals(true, mockBluetoothAdapter != null);
    }

    @Test
    public void shouldDisplayBluetoothRequestWhenDisabled() {

        mScanningPresenter.startScanning();

        PowerMockito.when(!mockBluetoothAdapter.isEnabled()).thenReturn(false);

        verify(mView).displayDialogRequestingBluetooth();
    }

我添加了 PowerMock 并创建了测试以确保它正常工作 ^^ 并且我正在添加测试以显示我想做什么但还不知道怎么做

我的想法是将此接口方法作为presenter 中的受保护方法并创建MockingClass。或者创建单独的界面助手并模拟它。

我对任何干净的解决方案/建议持开放态度。

每当我看到有人开始使用 Powermockito 进行新项目时,我都会立即想起 Padme 在第 3 集中对 Anakin 说的话:

You're going down a path I can't follow

这里不需要 Powermockito - 只需要旧的 Java 和 Mockito :-)

您的 Presenter 中有一些 public 方法,可能应该将其提取出来以分隔 类。最好的演示者只需将他们的操作委托给其他 类 并使用 show 方法操纵视图。这是演示者的唯一责任。你可以很容易地做这样的事情:

class PermissionsChecker {

   private final Context context;

   PermissionsChecker(Context context) {
       this.context = context;
   }

    public boolean isLocationPermissionGranted() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
            return false;
        if (context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
            return false;
        return true;
   }
}

然后:

class BluetoothAdapterWrapper {

    private final BluetoothAdapter bluetoothAdapter;

    BluetoothAdapterWrapper(BluetoothAdapater adapter) { 
        this.bluetoothAdapter = adatper;
    }

    public boolean isBluetoothEnabled() {
        return bluetoothAdapter.isEnabled();
    }
}

现在您的演示者看起来像这样:

class ScanningPresenter {

    private final ScanningView scanningView;
    private final PermissionsChecker permissionsChecker;
    private final BluetoothAdapterWrapper bluetoothAdapterWrapper;

    ScanningPresenter(ScanningView scanningView, PermissionsChecker permissionsChecker, BluetoothAdapterWrapper bluetoothAdapterWrapper) {  
        this.scanningView = scanningView;
        this.permissionsChecker = permissionsChecker;
        this.bluetoothAdapterWrapper = bluetoothAdapterWrapper;
    }

    @Override
    public void startScanning() {
        if (isLocationPermissionGranted() && isBluetoothEnabled()) {
            scanningView.onStartScanBtnClick();
        } else if (!isBluetoothEnabled()) {
            scanningView.displayDialogRequestingBluetooth();
        } else if (!isLocationPermissionGranted()) {
            scanningView.displayDialogRequestingPermission();
        }
    }

    @Override
    public boolean isLocationPermissionGranted() {
        return permissionsChecker.isLocationPermissionGranted();
    }

    @Override
    public boolean isBluetoothEnabled() {
        return bluetoothAdapterWrapper.isEnabled();
    }
}

你注意到现在我们甚至不需要演示者的那些 public 方法 - 你可以从演示者的合同中删除它们并将它们设为私有或者如果你愿意完全摆脱它们。

现在你的测试看起来像这样:

@Mock PermissionsChecker mockPermissionsChecker;
@Mock BluetoothAdapterWrapper mockBluetoothAdapterWrapper;
@Mock ScanningView mockScanningView;

//system under test
ScanningPresenter scanningPresenter;

@Before
public void setUp() {
    MockitoAnnotations.init(this);
    scanningPresenter = new ScanningPresenter(mockScanningView, mockPermissionsChecker, mockBluetoothAdapterWrapper);
}

@Test
public void shouldDisplayBluetoothRequestWhenDisabled() {
    //arrange
    when(mockBluetoothAdapter.isEnabled()).thenReturn(false);

    //act
    mScanningPresenter.startScanning();

    //assert
    verify(mockScanningView).displayDialogRequestingBluetooth();
}