WorkManager menyediakan API untuk pengujian Worker, ListenableWorker, dan varian ListenableWorker (CoroutineWorker
dan RxWorker).
Menguji Pekerja
Anggaplah kita memiliki Worker yang terlihat seperti ini:
Kotlin
class SleepWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) { override fun doWork(): Result { // Sleep on a background thread. Thread.sleep(1000) return Result.success() } }
Java
public class SleepWorker extends Worker { public SleepWorker( @NonNull Context context, @NonNull WorkerParameters workerParameters) { super(context, workerParameters); } @NonNull @Override public Result doWork() { try { Thread.sleep(1000); } catch (InterruptedException ignore) { return Result.success(); } } }
Untuk menguji Worker ini, Anda dapat
menggunakan TestWorkerBuilder. Builder
ini membantu mem-build instance Worker yang dapat digunakan untuk tujuan
pengujian logika bisnis.
Kotlin
// 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())) } }
Java
@RunWith(AndroidJUnit4.class) public class SleepWorkerJavaTest { private Context context; private Executor executor; @Before public void setUp() { context = ApplicationProvider.getApplicationContext(); executor = Executors.newSingleThreadExecutor(); } @Test public void testSleepWorker() { SleepWorker worker = (SleepWorker) TestWorkerBuilder.from(context, SleepWorker.class, executor) .build(); Result result = worker.doWork(); assertThat(result, is(Result.success())); } }
TestWorkerBuilder juga dapat digunakan untuk menetapkan tag, seperti inputData atau
runAttemptCount, sehingga Anda dapat memverifikasi status pekerja secara terpisah. Perhatikan
contoh berikut, saat SleepWorker menggunakan durasi tidur sebagai data input
dan bukan konstanta yang ditetapkan di pekerja:
Kotlin
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" } }
Java
public class SleepWorker extends Worker { public static final String SLEEP_DURATION = "SLEEP_DURATION"; public SleepWorker( @NonNull Context context, @NonNull WorkerParameters workerParameters) { super(context, workerParameters); } @NonNull @Override public Result doWork() { try { long duration = getInputData().getLong(SLEEP_DURATION, 1000); Thread.sleep(duration); } catch (InterruptedException ignore) { return Result.success(); } } }
Di SleepWorkerTest, Anda dapat memberikan data input tersebut ke
TestWorkerBuilder untuk memenuhi kebutuhan SleepWorker.
Kotlin
// 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())) } }
Java
@RunWith(AndroidJUnit4.class) public class SleepWorkerJavaTest { private Context context; private Executor executor; @Before public void setUp() { context = ApplicationProvider.getApplicationContext(); executor = Executors.newSingleThreadExecutor(); } @Test public void testSleepWorker() { Data inputData = new Data.Builder() .putLong("SLEEP_DURATION", 1000L) .build(); SleepWorker worker = (SleepWorker) TestWorkerBuilder.from(context, SleepWorker.class, executor) .setInputData(inputData) .build(); Result result = worker.doWork(); assertThat(result, is(Result.success())); } }
Untuk detail selengkapnya tentang API TestWorkerBuilder, baca halaman referensi untuk
TestListenableWorkerBuilder, superclass TestWorkerBuilder.
Menguji ListenableWorker dan variannya
Untuk menguji ListenableWorker atau variannya
(CoroutineWorker
dan RxWorker), gunakan
TestListenableWorkerBuilder.
Perbedaan utama antara TestWorkerBuilder dan
TestListenableWorkerBuilder
adalah TestWorkerBuilder memungkinkan Anda menentukan latar belakang Executor yang digunakan untuk
menjalankan Worker, sedangkan TestListenableWorkerBuilder bergantung pada
logika thread implementasi ListenableWorker.
Misalnya, anggaplah kita perlu menguji CoroutineWorker yang terlihat seperti ini:
class SleepWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result {
delay(1000L) // milliseconds
return Result.success()
}
}
Untuk menguji SleepWorker, pertama-tama buat instance Pekerja menggunakan
TestListenableWorkerBuilder, lalu panggil fungsi doWork dalam
coroutine.
@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 logis sebagai builder coroutine untuk pengujian Anda agar setiap kode
yang dijalankan secara asinkron akan berjalan secara paralel.
Menguji implementasi RxWorker mirip dengan menguji CoroutineWorker, karena
TestListenableWorkerBuilder dapat menangani setiap subclass ListenableWorker.
Pertimbangkan versi SleepWorker yang menggunakan RxJava dan bukan coroutine.
Kotlin
class SleepWorker( context: Context, parameters: WorkerParameters ) : RxWorker(context, parameters) { override fun createWork(): Single<Result> { return Single.just(Result.success()) .delay(1000L, TimeUnit.MILLISECONDS) } }
Java
public class SleepWorker extends RxWorker { public SleepWorker(@NonNull Context appContext, @NonNull WorkerParameters workerParams) { super(appContext, workerParams); } @NonNull @Override public Single<Result> createWork() { return Single.just(Result.success()) .delay(1000L, TimeUnit.MILLISECONDS); } }
Versi SleepWorkerTest yang menguji RxWorker mungkin terlihat mirip dengan
versi yang menguji CoroutineWorker. Anda menggunakan TestListenableWorkerBuilder
yang sama, tetapi sekarang memanggil fungsi createWork
RxWorker. createWork menampilkan Single yang dapat digunakan untuk memverifikasi
perilaku pekerja. TestListenableWorkerBuilder menangani setiap kerumitan
threading dan menjalankan kode pekerja Anda secara paralel.
Kotlin
@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())) } } }
Java
@RunWith(AndroidJUnit4.class) public class SleepWorkerTest { private Context context; @Before public void setUp() { context = ApplicationProvider.getApplicationContext(); } @Test public void testSleepWorker() { SleepWorker worker = TestListenableWorkerBuilder.from(context, SleepWorker.class) .build(); worker.createWork().subscribe(result -> assertThat(result, is(Result.success()))); } }