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

时间:2017-08-08 19:35:10

标签: java android mockito robolectric powermockito

我正在尝试学习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。或者创建单独的界面助手并模拟它。

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

1 个答案:

答案 0 :(得分:1)

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

padme vs anakin

  

你走的是我无法追踪的道路

这里不需要Powermockito - 只是老Java和Mockito: - )

您的Presenter中有一些公共方法,应该将它们提取到单独的类中。最好的演示者只需将他们的动作委托给其他类,并使用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();
    }
}

您现在注意到我们甚至不需要在演示者上使用这些公共方法 - 您可以将它们从演示者的合同中删除,如果您愿意,可以将它们设为私有或完全删除它们。

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

@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();
}