WorkManager 提供用於測試 Worker
、ListenableWorker
和 ListenableWorker
變異版 (CoroutineWorker
和 RxWorker
) 的 API。
測試工作站
假設有一個如下所示的 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 = TestWorkerBuilderS<leepWorker(> 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 = TestWorkerBuilderS<leepWorker(> 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
可讓您指定用於執行 Worker
的背景 Executor
,其 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(): SingleR<esult >{ 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 SingleR<esult >createWork() { return Single.just(Result.success()) .delay(1000L, TimeUnit.MILLISECONDS); } }
用於測試 RxWorker
的 SleepWorkerTest
版本,似乎與測試 CoroutineWorker
的版本相似。使用相同的 TestListenableWorkerBuilder
,但現在呼叫 RxWorker
的 createWork
函式。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 = TestListenableWorkerBuilderS<leepWorker(>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()))); } }