การนำผู้ปฏิบัติงานทดสอบไปใช้งาน

WorkManager มี API สำหรับการทดสอบ Worker ListenableWorker และ ตัวแปร ListenableWorker ตัว (CoroutineWorker และ RxWorker)

ผู้ปฏิบัติงานทดสอบ

สมมติว่าเรามี Worker ซึ่งมีลักษณะดังนี้

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();
        }
    }
}

หากต้องการทดสอบ Worker นี้ คุณสามารถใช้ TestWorkerBuilder ช่วงเวลานี้ เครื่องมือสร้างช่วยสร้างอินสแตนซ์ของ Worker ที่ใช้เพื่อวัตถุประสงค์ การทดสอบตรรกะทางธุรกิจ

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 เพื่อตั้งค่าแท็ก เช่น inputData หรือ runAttemptCount เพื่อให้คุณยืนยันสถานะของผู้ปฏิบัติงานแยกต่างหากได้ พิจารณา ตัวอย่างที่ SleepWorker ใช้ระยะเวลาสลีปเป็นข้อมูลอินพุต แทนที่จะเป็นการเจาะจงที่ตัวพนักงานเอง:

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();
        }
    }
}

ใน SleepWorkerTest คุณสามารถระบุข้อมูลที่ป้อนไปยัง TestWorkerBuilder เพื่อตอบสนองความต้องการของ 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()));
    }
}

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ 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 ก่อนอื่น เราจะสร้างอินสแตนซ์ของผู้ปฏิบัติงานโดยใช้ 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 แทนโครูทีน

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);
    }
}

เวอร์ชันของ SleepWorkerTest ที่ทดสอบ RxWorker อ��จมีลักษณะคล้ายกับ เวอร์ชันที่ทดสอบ CoroutineWorker คุณใช้เหมือนเดิม TestListenableWorkerBuilder แต่ตอนนี้ได้โทรเข้าไปที่ createWork ของ RxWorker createWork จะแสดงผล Single ที่ใช้ยืนยัน พฤติกรรมของพนักงาน TestListenableWorkerBuilder จัดการชุดข้อความทั้งหมด มีความซับซ้อนและเรียกใช้โค้ดผู้ปฏิบัติงานควบคู่กัน

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())));
        }
}