Я недавно начал заниматься тестированием (TDD), и мне было интересно, сможет ли кто-нибудь пролить свет на практику, которую я делаю.Например, я проверяю, доступен ли поставщик местоположения, реализую класс контракта (источник данных) и оболочку, например:
LocationDataSource.kt
interface LocationDataSource {
fun isAvailable(): Observable<Boolean>
}
LocationUtil.kt
class LocationUtil(manager: LocationManager): LocationDataSource {
private var isAvailableSubject: BehaviorSubject<Boolean> =
BehaviorSubject.createDefault(manager.isProviderEnabled(provider))
override fun isAvailable(): Observable<Boolean> = locationSubject
}
Теперь, когда я тестирую, я не уверен, что делать дальше.Первое, что я сделал, это издевался над LocationManager
и isProviderEnabled
методом:
class LocationTest {
@Mock
private lateinit var context: Context
private lateinit var dataSource: LocationDataSource
private lateinit var manager: LocationManager
private val observer = TestObserver<Boolean>()
@Before
@Throws(Exception::class)
fun setUp(){
MockitoAnnotations.initMocks(this)
// override schedulers here
`when`(context.getSystemService(LocationManager::class.java))
.thenReturn(mock(LocationManager::class.java))
manager = context.getSystemService(LocationManager::class.java)
dataSource = LocationUtil(manager)
}
@Test
fun isProviderDisabled_ShouldReturnFalse(){
// Given
`when`(manager.isProviderEnabled(anyString())).thenReturn(false)
// When
dataSource.isLocationAvailable().subscribe(observer)
// Then
observer.assertNoErrors()
observer.assertValue(false)
}
}
Это работает.Тем не менее, во время моего исследования о том, как сделать то и это , время, потраченное на то, чтобы выяснить, как имитировать LocationManager
, было достаточно большим, чтобы (я думаю) нарушить одно из общих правил в TDD -тестовая реализация не должна занимать слишком много времени.
Итак, я решил, что будет лучше (и все еще в рамках области TDD) просто протестировать сам контракт (LocationDataSource
)?Насмешка dataSource
и последующая замена вышеприведенного теста на:
@Test
fun isProviderDisable_ShouldReturnFalse() {
// Given
`when`(dataSource.isLocationAvailable()).thenReturn(false)
// When
dataSource.isLocationAvailable().subscribe(observer)
// Then
observer.assertNoErrors()
observer.assertValue(false)
}
Это (очевидно) дало бы тот же результат без проблем с издевательством над LocationManager
.Но я думаю, что это противоречит цели теста - поскольку он фокусируется только на самом контракте, а не на фактическом классе, который его использует.
Я все еще думаю, что, возможно, первая практика все еще правильнапуть.Это поначалу просто нужно время, чтобы ознакомиться с насмешливыми классами Android.Но я хотел бы знать, что думают эксперты по TDD.