WorkManager میاناهای برنامهسازی کاربردیای برای آزمایش کردن Worker،
ListenableWorker، و
متغیرهای ListenableWorker
(CoroutineWorker
و RxWorker) ارائه میدهد.
آزمایش کردن کارگران
فرض کنید یک Worker داریم که به این شکل است:
class SleepWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) { override fun doWork(): Result { // Sleep on a background thread. Thread.sleep(1000) return Result.success() } }
برای آزمایش این Worker، میتوانید از
TestWorkerBuilder استفاده کنید. این
سازنده به ساختن نمونههای Worker کمک میکند که میتوانند برای هدف
آزمایش منطق کسبوکار استفاده شوند.
// 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 همچنین میتوان برای تنظیم برچسبهایی مثل inputData یا
runAttemptCount استفاده کرد تا بتوانید وضعیت کارگر را بهطور مجزا درستیسنجی کنید. مثالی را درنظر بگیرید که در آن SleepWorker مدت زمان خواب را بهعنوان داده ورودی دریافت میکند، بهجای اینکه این مقدار بهعنوان یک ثابت در 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" } }
در SleepWorkerTest، میتوانید آن دادههای ورودی را به
TestWorkerBuilder خود ارائه دهید تا نیازهای 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())) } }
برای جزئیات بیشتر درباره میانای برنامهسازی کاربردی TestWorkerBuilder، به صفحه مرجع
TestListenableWorkerBuilder،
ابرکلاس TestWorkerBuilder مراجعه کنید.
آزمایش کردن ListenableWorker و انواع آن
برای آزمایش ListenableWorker یا
انواع آن (CoroutineWorker
و RxWorker)، از
TestListenableWorkerBuilder استفاده کنید.
تفاوت اصلی بین TestWorkerBuilder و
TestListenableWorkerBuilder
این است که TestWorkerBuilder به شما امکان میدهد Executor پسزمینه استفادهشده برای
اجرای Worker را مشخص کنید، درحالیکه TestListenableWorkerBuilder به
منطق رشتهای پیادهسازی ListenableWorker متکی است.
برای مثال، فرض کنید باید CoroutineWorker را آزمایش کنیم که به این شکل است:
class SleepWorker(context: Context, parameters: WorkerParameters) : CoroutineWorker(context, parameters) { override suspend fun doWork(): Result { delay(1000L) // milliseconds return Result.success() } }
برای آزمایش SleepWorker، ابتدا نمونهای از Worker را بااستفاده از
TestListenableWorkerBuilder ایجاد میکنیم و سپس تابع doWork آن را در یک
روال همگام فراخوانی میکنیم.
@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 بهعنوان سازنده همروال برای آزمایشهای شما منطقی است تا هر کدی
که بهصورت ناهمگام اجرا میشود، بهجای آن بهصورت موازی اجرا شود.
آزمایش کردن پیادهسازی RxWorker مشابه آزمایش کردن CoroutineWorker است، زیرا
TestListenableWorkerBuilder میتواند هر زیرکلاس ListenableWorker را مدیریت کند.
نسخهای از SleepWorker را درنظر بگیرید که بهجای روالهای همزمان از RxJava استفاده میکند.
class SleepWorker( context: Context, parameters: WorkerParameters ) : RxWorker(context, parameters) { override fun createWork(): Single<Result> { return Single.just(Result.success()) .delay(1000L, TimeUnit.MILLISECONDS) } }
نسخهای از SleepWorkerTest که RxWorker را آزمایش میکند ممکن است شبیه به
نسخهای باشد که CoroutineWorker را آزمایش کرده است. از همان
TestListenableWorkerBuilder استفاده میکنید
اما اکنون تابع createWork مربوط به RxWorker را فراخوانی میکنید. createWork یک Single برمیگرداند که میتوانید از آن برای درستیسنجی کردن
رفتار کارگرتان استفاده کنید. TestListenableWorkerBuilder هرگونه پیچیدگی رشتهای را مدیریت میکند و کد کارگر شما را بهصورت موازی اجرا میکند.
@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())) } } }