Test dell'implementazione del worker

WorkManager fornisce le API per i test di Worker, ListenableWorker e ListenableWorker varianti (CoroutineWorker) e RxWorker).

Worker per i test

Supponiamo di avere un Worker simile a questo:

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

Per testare questo Worker, puoi usare TestWorkerBuilder Questo aiuta a creare istanze di Worker che possono essere utilizzate ai fini di testare la logica di business.

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 può essere utilizzato anche per impostare tag, ad esempio inputData o runAttemptCount, in modo da poter verificare lo stato del worker in modo isolato. Prendi in considerazione un esempio in cui SleepWorker prende la durata del sonno come dati di input invece di essere una costante definita nel worker:

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

In SleepWorkerTest, puoi fornire questi dati di input al tuo TestWorkerBuilder per soddisfare le esigenze di 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()));     } } 

Per maggiori dettagli sull'API TestWorkerBuilder, consulta la pagina di riferimento per TestListenableWorkerBuilder, la superclasse TestWorkerBuilder.

Test di ListenableWorker e delle sue varianti

Per testare un elemento ListenableWorker o la relativa varianti (CoroutineWorker e RxWorker), utilizza TestListenableWorkerBuilder. La differenza principale tra TestWorkerBuilder e a TestListenableWorkerBuilder è che TestWorkerBuilder ti consente di specificare lo sfondo Executor utilizzato eseguire Worker, mentre TestListenableWorkerBuilder si basa della logica di thread dell'implementazione di ListenableWorker.

Ad esempio, supponiamo di dover testare un CoroutineWorker che ha questo aspetto:

class SleepWorker(context: Context, parameters: WorkerParameters) :     CoroutineWorker(context, parameters) {     override suspend fun doWork(): Result {         delay(1000L) // milliseconds         return Result.success()     } } 

Per testare SleepWorker, creiamo prima un'istanza del worker utilizzando TestListenableWorkerBuilder e quindi richiamare la relativa funzione doWork all'interno di un 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 ha senso come strumento per la creazione di coroutine per i tuoi test, in modo che qualsiasi codice che verrebbe eseguito in modo asincrono, viene eseguito in parallelo.

Il test di un'implementazione RxWorker è simile al test di CoroutineWorker, poiché TestListenableWorkerBuilder può gestire qualsiasi sottoclasse di ListenableWorker. Prendi in considerazione una versione di SleepWorker che utilizzi RxJava anziché coroutine.

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

Una versione di SleepWorkerTest che esegue il test di un RxWorker può essere simile alla che ha testato un CoroutineWorker. Utilizzi lo stesso TestListenableWorkerBuilder ma ora chiama createWork di RxWorker personalizzata. createWork restituisce un Single che puoi utilizzare per verificare il comportamento del worker. TestListenableWorkerBuilder gestisce tutti i thread complessità ed esegue il codice worker in parallelo.

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