Google 致力于为黑人社区推动种族平等。查看具体举措

测试 Worker 实现

从版本 2.1.0 开始,WorkManager 提供了用于测试 WorkerListenableWorkerListenableWorker 变体(CoroutineWorkerRxWorker)的 API。

在版本 2.1.0 以前,要测试工作器,您需要使用 WorkManagerTestInitHelper 来初始化 WorkManager。在 2.1.0 中,如果要测试 Worker 的实现,将无需使用 Worker

测试 ListenableWorker 及其变体

要测试 ListenableWorker 或其变体(CoroutineWorkerRxWorker),请使用 TestListenableWorkerBuilder。此构建器有助于构建可用于测试 Worker 业务逻辑的 ListenableWorker 实例。

例如,假设我们需要测试类似以下示例的 CoroutineWorker

Kotlin

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

    

Java

    public class SleepWorker extends ListenableWorker {
        private final ResolvableFuture<Result> mResult;
        private final Handler mHandler;
        private final Object mLock;
        private Runnable mRunnable;
        public SleepWorker(
                @NonNull Context context,
                @NonNull WorkerParameters workerParameters) {
            super(context, workerParameters);
            mHandler = new Handler(Looper.getMainLooper());
            mResult = new ResolvableFuture<>();
            mLock = new Object();
        }

        @NonNull
        @Override
        public ListenableFuture<Result> startWork() {
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    synchronized (mLock) {
                        mResult.set(Result.success());
                    }
                }
            };

            mHandler.postDelayed(mRunnable, 1000L);
            return mResult;
        }

        @Override
        public void onStopped() {
            super.onStopped();
            if (mRunnable != null) {
                mHandler.removeCallbacks(mRunnable);
            }
            synchronized (mLock) {
                if (!mResult.isDone()) {
                    mResult.set(Result.failure());
                }
            }
        }
    }

    

要测试 SleepWorker,我们首先使用 TestListenableWorkerBuilder 创建一个工作器实例。此构建器还可用于设置标记、inputDatarunAttemptCount 等。有关详情,请参见 TestListenableWorker 参考页面。

Kotlin

    @RunWith(AndroidJUnit4::class)
    class SleepWorkerTest {
        private lateinit var context: Context

        @Before
        fun setUp() {
            context = ApplicationProvider.getApplicationContext()
        }

        @Test
        fun testSleepWorker() {
            // Kotlin code can use the TestListenableWorkerBuilder extension to
            // build the ListenableWorker
            val worker = TestListenableWorkerBuilder<SleepWorker>(context).build()
            runBlocking {
                val result = worker.doWork()
                assertThat(result, `is`(Result.success()))
            }
        }
    }

    

Java

    @RunWith(AndroidJUnit4.class)
    public class SleepWorkerJavaTest {
        private Context mContext;

        @Before
        public void setUp() {
            mContext = ApplicationProvider.getApplicationContext();
        }

        @Test
        public void testSleepWorker() throws Exception {
           ListenableWorker worker =
               TestListenableWorkerBuilder.from(mContext, SleepWorker.class)
                       .build();

            Result result = worker.startWork().get();
            assertThat(result, is(Result.success()));
        }
    }
    

测试工作器

假设我们有一个类似以下示例的 Worker

Kotlin

    class SleepWorker(context: Context, parameters: WorkerParameters) :
        Worker(context, parameters) {

        companion object {
            const val SLEEP_DURATION = "SLEEP_DURATION"
        }

        override fun doWork(): Result {
            // Sleep on a background thread.
            val sleepDuration = inputData.getLong(SLEEP_DURATION, 1000)
            Thread.sleep(sleepDuration)
            return Result.success()
        }
    }

    

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

    

要测试这个 Worker,您现在可以使用 TestWorkerBuilderTestWorkerBuilderTestListenableWorkerBuilder 的主要区别在于,TestWorkerBuilder 允许指定用来运行 Worker 的后台 Executor

Kotlin

    // Kotlin code can use 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 10000L)
            ).build()

            val result = worker.doWork()
            assertThat(result, `is`(Result.success()))
        }
    }

    

Java


    @RunWith(AndroidJUnit4.class)
    public class SleepWorkerJavaTest {
        private Context mContext;
        private Executor mExecutor;

        @Before
        public void setUp() {
            mContext = ApplicationProvider.getApplicationContext();
            mExecutor = Executors.newSingleThreadExecutor();
        }

        @Test
        public void testSleepWorker() {
            Data inputData = new Data.Builder()
                    .putLong("SLEEP_DURATION", 10_000L)
                    .build();

            SleepWorker worker =
                    (SleepWorker) TestWorkerBuilder.from(mContext,
                            SleepWorker.class,
                            mExecutor)
                            .setInputData(inputData)
                            .build();

            Result result = worker.doWork();
            assertThat(result, is(Result.success()));
        }
    }