【问题标题】:Mockito test check if bluetooth is enabledMockito 测试检查是否启用了蓝牙
【发布时间】:2017-08-08 19:35:10
【问题描述】:

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

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

【问题讨论】:

    标签: java android mockito robolectric powermockito


    【解决方案1】:

    每当我看到有人开始将 Powermockito 用于新项目时,我都会立即想起 Padme 在第 3 集中对 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();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-05
      • 2014-09-14
      • 2018-04-27
      • 2013-02-19
      • 2013-05-01
      • 1970-01-01
      • 2016-05-28
      • 2020-07-30
      相关资源
      最近更新 更多