Как правильно написать коратину модульные тестыAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как правильно написать коратину модульные тесты

Сообщение Anonymous »

Это мой производственный класс, и теперь мне нужно написать модульный тест для метода Startreconnectloop, но код для модульного тестирования, который я написал, заставляет производственный код ввести бесконечный цикл. Не могли бы вы помочь мне решить эту проблему? Большое спасибо. < /P>

Код: Выделить всё

@Singleton
class EditorServiceConnection @Inject constructor(
@ApplicationContext private val context: Context,
@IoDispatcher private val ioScope: CoroutineScope,
) : ServiceConnection {

private val _service = MutableStateFlow(null)
val service get() = _service.asStateFlow().filterNotNull()
private var reconnectJob: Job? = null
private var isBound = false

fun bindService() {
val intent = Intent().apply {
setAction("com.scene.engine.service.action")
setComponent(
ComponentName(
"com.scene.engine",
"com.scene.engine.EngineService"
)
)
}
context.bindService(intent, this, Context.BIND_AUTO_CREATE)
}

fun unbindService() {
context.unbindService(this)
}

override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
LogUtil.d(TAG, "Service connected.")
val engine = IEngine.Stub.asInterface(binder)
val engineApi = IEditorApi.Stub.asInterface(engine.obtainEditorApi())
engineApi.registerApiStatusCallback(object : IApiStatusCallback.Stub() {
override fun onApiInitialized() {
LogUtil.d(TAG, "onApiInitialized.")
_service.update { engineApi }
}
})
isBound = true
}

override fun onServiceDisconnected(name: ComponentName?) {
LogUtil.e(TAG, "Service disconnected.")
_service.update { null }
isBound = false
startReconnectLoop()
}

private fun startReconnectLoop() {
LogUtil.e(TAG, "Service startReconnectLoop.")
reconnectJob?.cancel()
reconnectJob = ioScope.launch {
while (!isBound) {
delay(2000)
if (!isBound) {
try {
LogUtil.d(TAG, "try bind service.")
bindService()
} catch (e: Exception) {
LogUtil.e(TAG, e.toString())
}
}
}
}
}

companion object {
private const val TAG = "EditorServiceConnection"
}
}
< /code>
Ниже приведен мой метод испытаний. При отладке я обнаружил, что Connection.SetPrivateField («iSbound», True) 
не выполнялся, и производственный код ввел некоторое время Infinite Loop.
@OptIn(ExperimentalCoroutinesApi::class)
class EditorServiceConnectionTest {

@MockK
private lateinit var mockContext: Context

@MockK
private lateinit var mockBinder: IBinder

private val testDispatcher = StandardTestDispatcher()
private val testScope = TestScope(testDispatcher)

private lateinit var connection: EditorServiceConnection

@Before
fun setup() {
MockKAnnotations.init(this)
Dispatchers.setMain(testDispatcher)
mockkStatic(XLog::class)
every { XLog.init(any(), any(), any()) } just Runs
every { XLog.tag(any()).d(any()) } just Runs
every { XLog.tag(any()).e(any()) } just Runs
connection = EditorServiceConnection(mockContext, testScope)
}

@After
fun tearDown() {
Dispatchers.resetMain()
unmockkAll()
}

@Test
fun `onServiceDisconnected should invoke startReconnectLoop`() = runTest {

connection.onServiceDisconnected(null)

advanceTimeBy(2000)
verify(exactly = 1) { connection.bindService() }

connection.setPrivateField("isBound", true)

advanceTimeBy(2000)
verify(exactly = 1) { connection.bindService() }
}
}

fun Any.setPrivateField(name: String, value: T) {
val field = this::class.java.getDeclaredField(name)
field.isAccessible = true
field.set(this, value)
}
< /code>
Я не знаю, в чем проблема. Когда я строю объект EditorServiceConnection, я прохожу в TestScope.

Подробнее здесь: https://stackoverflow.com/questions/796 ... -correctly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»