public final class

WorkManagerTestInitHelper

extends java.lang.Object

 java.lang.Object

↳androidx.work.testing.WorkManagerTestInitHelper

Gradle dependencies

compile group: 'androidx.work', name: 'work-testing', version: '2.10.0-alpha03'

  • groupId: androidx.work
  • artifactId: work-testing
  • version: 2.10.0-alpha03

Artifact androidx.work:work-testing:2.10.0-alpha03 it located at Google repository (https://maven.google.com/)

Overview

Helps initialize WorkManager for testing.

Summary

Methods
public static voidcloseWorkDatabase()

Closes internal WorkManager's database.

public static TestDrivergetTestDriver()

public static TestDrivergetTestDriver(Context context)

public static voidinitializeTestWorkManager(Context context)

Initializes a test WorkManager with a SynchronousExecutor.

public static voidinitializeTestWorkManager(Context context, Configuration configuration)

Initializes a test WorkManager with a user-specified Configuration, but using SynchronousExecutor instead of main thread.

public static voidinitializeTestWorkManager(Context context, Configuration configuration, WorkManagerTestInitHelper.ExecutorsMode executorsMode)

Initializes a test WorkManager that can be controlled via TestDriver.

public static voidinitializeTestWorkManager(Context context, WorkManagerTestInitHelper.ExecutorsMode executorsMode)

Initializes a test WorkManager that can be controlled via TestDriver.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public static void initializeTestWorkManager(Context context)

Initializes a test WorkManager with a SynchronousExecutor.

Parameters:

context: The application

public static void initializeTestWorkManager(Context context, Configuration configuration)

Initializes a test WorkManager with a user-specified Configuration, but using SynchronousExecutor instead of main thread.

Parameters:

context: The application
configuration: The Configuration

public static void initializeTestWorkManager(Context context, Configuration configuration, WorkManagerTestInitHelper.ExecutorsMode executorsMode)

Initializes a test WorkManager that can be controlled via TestDriver.

Parameters:

context: The application
configuration: test configuration of WorkManager
executorsMode: mode controlling executors used by WorkManager in tests. See documentation of modes in WorkManagerTestInitHelper.ExecutorsMode

public static void initializeTestWorkManager(Context context, WorkManagerTestInitHelper.ExecutorsMode executorsMode)

Initializes a test WorkManager that can be controlled via TestDriver.

Parameters:

context: The application
executorsMode: mode controlling executors used by WorkManager in tests. See documentation of modes in WorkManagerTestInitHelper.ExecutorsMode

public static TestDriver getTestDriver()

Deprecated: Call WorkManagerTestInitHelper.getTestDriver(Context) instead.

Returns:

An instance of TestDriver. This exposes additional functionality that is useful in the context of testing when using WorkManager.

public static TestDriver getTestDriver(Context context)

Returns:

An instance of TestDriver. This exposes additional functionality that is useful in the context of testing when using WorkManager.

public static void closeWorkDatabase()

Closes internal WorkManager's database.

It could be helpful to avoid warnings by CloseGuard in testing infra. You need to be make sure that WorkManager finished all operations and won't touch database anymore. Meaning that both Configuration.getTaskExecutor() and Configuration.getExecutor() are idle.

It shouldn't be called from Configuration.getTaskExecutor() because this method will block until all internal work is complete after cancellation. To complete this work Configuration.getTaskExecutor() could be require and blocking it may lead to deadlocks.

Source

/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.work.testing;

import static androidx.work.testing.TestWorkManagerImplKt.createTestWorkManagerImpl;
import static androidx.work.testing.WorkManagerTestInitHelper.ExecutorsMode.LEGACY_OVERRIDE_WITH_SYNCHRONOUS_EXECUTORS;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.work.Configuration;
import androidx.work.impl.WorkManagerImpl;
import androidx.work.impl.utils.SerialExecutorImpl;
import androidx.work.impl.utils.taskexecutor.SerialExecutor;

import java.util.UUID;


/**
 * Helps initialize {@link androidx.work.WorkManager} for testing.
 */
public final class WorkManagerTestInitHelper {
    /**
     * Initializes a test {@link androidx.work.WorkManager} with a {@link SynchronousExecutor}.
     *
     * @param context The application {@link Context}
     */
    public static void initializeTestWorkManager(@NonNull Context context) {
        SynchronousExecutor synchronousExecutor = new SynchronousExecutor();
        Configuration configuration = new Configuration.Builder()
                .setExecutor(synchronousExecutor)
                .setTaskExecutor(synchronousExecutor)
                .build();
        initializeTestWorkManager(context, configuration);
    }

    /**
     * Initializes a test {@link androidx.work.WorkManager} with a user-specified
     * {@link androidx.work.Configuration}, but using
     * {@link SynchronousExecutor} instead of main thread.
     *
     * @param context       The application {@link Context}
     * @param configuration The {@link androidx.work.Configuration}
     */
    public static void initializeTestWorkManager(
            @NonNull Context context,
            @NonNull Configuration configuration) {
        initializeTestWorkManager(context, configuration,
                LEGACY_OVERRIDE_WITH_SYNCHRONOUS_EXECUTORS);
    }

    /**
     * Modes that control which executors are used in tests.
     */
    public enum ExecutorsMode {
        /**
         * Use executors as they are configured in passed {@link Configuration} and preserving
         * real main thread.
         */
        PRESERVE_EXECUTORS,

        /**
         * Preserve old behavior of {@link #initializeTestWorkManager(Context)} and
         * {@link #initializeTestWorkManager(Context, Configuration)}.
         *
         * <p> In this mode {@link SynchronousExecutor} is used instead of main thread. Similarly,
         * {@link SynchronousExecutor} is used as {@link Configuration#getTaskExecutor()}, unless
         * {@link Configuration#getTaskExecutor()} was explicitly set in {@code configuration}
         * passed in {@link #initializeTestWorkManager(Context, Configuration, ExecutorsMode)}
         */
        LEGACY_OVERRIDE_WITH_SYNCHRONOUS_EXECUTORS,

        /**
         * Like {@link #PRESERVE_EXECUTORS}, but uses the real Clock and RunnableScheduler in
         * the provided {@link Configuration} instead of the {@link TestDriver} setDelayMet()
         * methods to run scheduled work.
         *
         * <p> Work will be passed to RunnableScheduler with appropriate time-based delay, and the
         * RunnableScheduler must reschedule the work itself when the clock delay has passed.
         *
         * {@link TestDriver#setInitialDelayMet(UUID)} and
         * {@link TestDriver#setPeriodDelayMet(UUID)}
         * throw exceptions when this configuration is used.
         *
         * <p> This mode is intended for integrated fake clock / schedule test frameworks, eg.
         * {@link kotlinx.coroutines.test.StandardTestDispatcherImpl} with
         * {@link kotlinx.coroutines.test.TestCoroutineScheduler}
         */
        USE_TIME_BASED_SCHEDULING,
    }

    /**
     * Initializes a test {@link androidx.work.WorkManager} that can be controlled via {@link
     * TestDriver}.
     *
     * @param context       The application {@link Context}
     * @param configuration test configuration of WorkManager
     * @param executorsMode mode controlling executors used by WorkManager in tests. See
     *                      documentation of modes in {@link ExecutorsMode}
     */
    public static void initializeTestWorkManager(@NonNull Context context,
            @NonNull Configuration configuration, @NonNull ExecutorsMode executorsMode) {
        WorkManagerImpl workManager;
        switch (executorsMode) {
            case LEGACY_OVERRIDE_WITH_SYNCHRONOUS_EXECUTORS:
                SerialExecutor serialExecutor;
                if (configuration.isUsingDefaultTaskExecutor()) {
                    Configuration.Builder builder = new Configuration.Builder(configuration)
                            .setTaskExecutor(new SynchronousExecutor());
                    configuration = builder.build();
                    serialExecutor = new SynchronousSerialExecutor();
                } else {
                    serialExecutor = new SerialExecutorImpl(configuration.getTaskExecutor());
                }
                workManager = createTestWorkManagerImpl(
                        context, configuration, serialExecutor, executorsMode);
                break;
            case PRESERVE_EXECUTORS:
            case USE_TIME_BASED_SCHEDULING:
                workManager = createTestWorkManagerImpl(
                        context, configuration, executorsMode);
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + executorsMode);
        }
        WorkManagerImpl.setDelegate(workManager);
    }

    /**
     * Initializes a test {@link androidx.work.WorkManager} that can be controlled via {@link
     * TestDriver}.
     *
     * @param context       The application {@link Context}
     * @param executorsMode mode controlling executors used by WorkManager in tests. See
     *                      documentation of modes in {@link ExecutorsMode}
     */
    public static void initializeTestWorkManager(@NonNull Context context,
            @NonNull ExecutorsMode executorsMode) {
        Configuration configuration;
        if (executorsMode == LEGACY_OVERRIDE_WITH_SYNCHRONOUS_EXECUTORS) {
            SynchronousExecutor synchronousExecutor = new SynchronousExecutor();
            configuration = new Configuration.Builder()
                    .setExecutor(synchronousExecutor)
                    .setTaskExecutor(synchronousExecutor)
                    .build();
        } else {
            configuration = new Configuration.Builder().build();
        }
        initializeTestWorkManager(context, configuration, executorsMode);
    }

    /**
     * @return An instance of {@link TestDriver}. This exposes additional functionality that is
     * useful in the context of testing when using WorkManager.
     * @deprecated Call {@link WorkManagerTestInitHelper#getTestDriver(Context)} instead.
     */
    @Deprecated
    public static @Nullable TestDriver getTestDriver() {
        WorkManagerImpl workManager = WorkManagerImpl.getInstance();
        if (workManager == null) {
            return null;
        } else {
            return TestWorkManagerImplKt.getTestDriver(workManager);
        }
    }

    /**
     * @return An instance of {@link TestDriver}. This exposes additional functionality that is
     * useful in the context of testing when using WorkManager.
     */
    public static @Nullable TestDriver getTestDriver(@NonNull Context context) {
        try {
            return TestWorkManagerImplKt.getTestDriver(WorkManagerImpl.getInstance(context));
        } catch (IllegalStateException e) {
            return null;
        }
    }

    /**
     * Closes internal {@link androidx.work.WorkManager}'s database.
     * <p>
     * It could be helpful to avoid warnings by CloseGuard in testing infra. You need to be
     * make sure that {@code WorkManager} finished all operations and won't touch database
     * anymore. Meaning that both {@link Configuration#getTaskExecutor()} and
     * {@link Configuration#getExecutor()} are idle.
     * <p>
     * It shouldn't be called from {@link Configuration#getTaskExecutor()}
     * because this method will block until all internal work is complete after
     * cancellation. To complete this work {@link Configuration#getTaskExecutor()}
     * could be require and blocking it may lead to deadlocks.
     */
    @SuppressWarnings("deprecation")
    public static void closeWorkDatabase() {
        WorkManagerImpl workManager = WorkManagerImpl.getInstance();
        if (workManager != null) {
            workManager.closeDatabase();
        }
    }

    private WorkManagerTestInitHelper() {
    }
}