작업자 구현 테스트

버전 2.1.0부터 WorkManager는 Worker, ListenableWorkerListenableWorker 변형(CoroutineWorkerRxWorker) 테스트를 위한 API를 제공합니다.

버전 2.1.0 이전에는 작업자를 테스트하려면 WorkManagerTestInitHelper를 사용하여 WorkManager를 초기화해야 했습니다. 2.1.0에서는 Worker 구현을 테스트할 때 WorkManagerTestInitHelper를 사용할 필요가 없습니다.

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

    

자바

    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를 사용하여 Worker의 인스턴스를 생성합니다. 또한 이 빌더를 사용하여 태그, inputData, runAttemptCount 등을 설정할 수도 있습니다. 자세한 내용은 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()))
            }
        }
    }

    

자바

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

    

자바

    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를 테스트하려면 이제 TestWorkerBuilder를 사용할 수 있습니다. TestWorkerBuilderTestListenableWorkerBuilder의 주요 차이점은 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()))
        }
    }

    

자바


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