2017-08-08 44 views
0

我正在嘗試學習Mockito和TDD。Mockito測試檢查是否啓用藍牙

我有演示用的方法:

@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或瓦特/電子底部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和創建的測試,以確保它的工作^^和我加入測試,顯示我想要做什麼,但不知道我的想法是如何尚未

將此接口方法作爲演示者中的受保護方法並創建MockingClass。或者創建單獨的接口幫助器並對其進行嘲弄。

我對任何清潔解決方案/主張都抱有開放態度。

回答

1

每當我看到有人開始使用Powermockito一個新的項目,我馬上在第3集想到帕德梅的話阿納金:

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

該死。超級好的迴應。 「謝謝你,我的主人」 – Esperanz0