WorkManager มี API สำหรับทดสอบ 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 API ได้ที่หน้าข้อมูลอ้างอิงสำหรับ 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 ภายใน 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 เหมาะสมที่จะเป็น Coroutine Builder สำหรับการทดสอบของคุณ เพื่อให้โค้ดที่ควรจะทำงานแบบอะซิงโครนัสทำงานแบบคู่ขนานแทน
การทดสอบการติดตั้งใช้งาน RxWorker คล้ายกับการทดสอบ CoroutineWorker เนื่องจาก TestListenableWorkerBuilder สามารถจัดการคลาสย่อยของ ListenableWorker ได้
ลองพิจารณาใช้ SleepWorker เวอร์ชันที่ใช้ RxJava แทน Coroutine
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 จะจัดการความซับซ้อนของชุดข้อความและเรียกใช้โค้ด Worker พร้อมกัน
@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())) } } }