O WorkManager fornece APIs para testar Worker,
ListenableWorker e as
variantes ListenableWorker
(CoroutineWorker
e RxWorker).
Testar workers
Suponhamos que temos um Worker parecido com o seguinte:
class SleepWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) { override fun doWork(): Result { // Sleep on a background thread. Thread.sleep(1000) return Result.success() } }
Para testar Worker, você pode usar
TestWorkerBuilder. Esse
criador ajuda a criar instâncias do Worker que podem ser usadas com a finalidade de
testar a lógica de negócios.
// Kotlin code uses the TestWorkerBuilder extension to build // the Worker @RunWith(AndroidJUnit4::class) class SleepWorkerTest { private lateinit var context: Context private lateinit var executor: Executor @Before fun setUp() { context = ApplicationProvider.getApplicationContext() executor = Executors.newSingleThreadExecutor() } @Test fun testSleepWorker() { val worker = TestWorkerBuilder<SleepWorker>( context = context, executor = executor ).build() val result = worker.doWork() assertThat(result, `is`(Result.success())) } }
TestWorkerBuilder também pode ser usado para definir tags, como inputData ou
runAttemptCount, para que você possa verificar o estado do worker isoladamente. Considere
um exemplo em que SleepWorker assume uma duração de suspensão como dados de entrada,
em vez de ser uma constante definida no worker:
class SleepWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) { override fun doWork(): Result { // Sleep on a background thread. val sleepDuration = inputData.getLong(SLEEP_DURATION, 1000) Thread.sleep(sleepDuration) return Result.success() } companion object { const val SLEEP_DURATION = "SLEEP_DURATION" } }
Em SleepWorkerTest, você pode fornecer esses dados de entrada para seu
TestWorkerBuilder para atender às necessidades de SleepWorker.
// Kotlin code uses the TestWorkerBuilder extension to build // the Worker @RunWith(AndroidJUnit4::class) class SleepWorkerTest { private lateinit var context: Context private lateinit var executor: Executor @Before fun setUp() { context = ApplicationProvider.getApplicationContext() executor = Executors.newSingleThreadExecutor() } @Test fun testSleepWorker() { val worker = TestWorkerBuilder<SleepWorker>( context = context, executor = executor, inputData = workDataOf("SLEEP_DURATION" to 1000L) ).build() val result = worker.doWork() assertThat(result, `is`(Result.success())) } }
Para mais detalhes sobre a API TestWorkerBuilder, consulte a página de referência para
TestListenableWorkerBuilder,
a superclasse de TestWorkerBuilder.
Testar o ListenableWorker e as respectivas variantes
Para testar um ListenableWorker ou
as variantes (CoroutineWorker
e RxWorker ), use
TestListenableWorkerBuilder.
A principal diferença entre TestWorkerBuilder e um
TestListenableWorkerBuilder
é que TestWorkerBuilder permite que você especifique o Executor de segundo plano usado para
executar o Worker, enquanto TestListenableWorkerBuilder depende da
lógica de linha de execução da implementação de ListenableWorker.
Por exemplo, suponha que precisamos testar um CoroutineWorker parecido com o seguinte:
class SleepWorker(context: Context, parameters: WorkerParameters) : CoroutineWorker(context, parameters) { override suspend fun doWork(): Result { delay(1000L) // milliseconds return Result.success() } }
Para testar SleepWorker, primeiro criamos uma instância do Worker usando
TestListenableWorkerBuilder e, em seguida, chamamos a função doWork em uma
corrotina.
@RunWith(AndroidJUnit4::class) class SleepWorkerTest { private lateinit var context: Context @Before fun setUp() { context = ApplicationProvider.getApplicationContext() } @Test fun testSleepWorker() { val worker = TestListenableWorkerBuilder<SleepWorker>(context).build() runBlocking { val result = worker.doWork() assertThat(result, `is`(Result.success())) } } }
runBlocking faz sentido como um construtor de corrotinas para seus testes, de modo que qualquer código
executado de forma assíncrona é executado em paralelo.
Testar uma implementação de RxWorker é semelhante a testar CoroutineWorker, porque
TestListenableWorkerBuilder pode processar qualquer subclasse de ListenableWorker.
Considere uma versão de SleepWorker que use RxJava em vez de corrotinas.
class SleepWorker( context: Context, parameters: WorkerParameters ) : RxWorker(context, parameters) { override fun createWork(): Single<Result> { return Single.just(Result.success()) .delay(1000L, TimeUnit.MILLISECONDS) } }
Uma versão de SleepWorkerTest que testa um RxWorker pode ser semelhante à
versão que testou um CoroutineWorker. Você usa o mesmo
TestListenableWorkerBuilder, mas agora chama a função createWork
do RxWorker. createWork retorna um Single que pode ser usado para verificar o
comportamento do worker. TestListenableWorkerBuilder processa as complexidades de linha de execução
e executa o código do worker em paralelo.
@RunWith(AndroidJUnit4::class) class SleepWorkerTest { private lateinit var context: Context @Before fun setUp() { context = ApplicationProvider.getApplicationContext() } @Test fun testSleepWorker() { val worker = TestListenableWorkerBuilder<SleepWorker>(context).build() worker.createWork().subscribe { result -> assertThat(result, `is`(Result.success())) } } }