5

当我尝试在包含 WorkManager 的应用程序中运行 ActivityScenario 时,我在启动时收到以下错误:

java.lang.IllegalStateException: WorkManager is not initialized properly.  You have explicitly disabled WorkManagerInitializer in your manifest, have not manually called WorkManager#initialize at this point, and your Application does not implement Configuration.Provider.

使用WorkManagerTestInitHelper来自work-test工件的 也无济于事。

WorkManager 的定义如下:

@Provides
@Singleton
fun provideWorkmanager(@ApplicationContext context: Context) = WorkManager.getInstance(context)

这是我的测试自动取款机:

    @HiltAndroidTest
    @RunWith(AndroidJUnit4::class)
    class LoginTest {
    
        @get:Rule(order = 0)
        var hiltRule = HiltAndroidRule(this)
    
        @get:Rule(order = 1)
        val activityRule = ActivityScenarioRule(MainActivity::class.java)
    
        @Before
        fun before() {
            val context = InstrumentationRegistry.getInstrumentation().targetContext
            val config = Configuration.Builder()
                .setMinimumLoggingLevel(Log.DEBUG)
                .setExecutor(SynchronousExecutor())
                .build()
            WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
        }
    
        @Test
        fun test() {
            ...
        }

}
4

2 回答 2

1

为了利用ActivitScenarioRule并确保WorkManager首先初始化,我创建了一个自定义 JUnit 规则。

class WorkManagerRule : TestRule {
override fun apply(base: Statement?, description: Description?): Statement {
    return object : Statement() {
        override fun evaluate() {
            val context = InstrumentationRegistry.getInstrumentation().targetContext
            val config = Configuration.Builder()
                .setMinimumLoggingLevel(Log.DEBUG)
                .setExecutor(SynchronousExecutor())
                .build()
            WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
            try {
                base?.evaluate()
            } finally {
                Log.d("WorkManagerRule", "Do some teardown")
            }
        }

    }
}


@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
class MyTest {
    @get:Rule(order = 0)
    var hiltRule = HiltAndroidRule(this)

    @get:Rule(order = 1)
    var workMgrRule = WorkManagerRule()

    @get:Rule(order = 2)
    var activityRule = ActivityScenarioRule(MainActivity::class.java)

    @Before
    fun init() {
        hiltRule.inject()
    }

    //Your test code here...
}

我使用了此处找到的创建 JUnit 规则的说明。

于 2021-05-28T23:35:52.710 回答
1

这是因为根据Google 文档,在@get:Rule执行之前执行:@Before

此规则提供单个活动的功能测试。被测活动在使用@Test 注释的每个测试之前以及在使用@Before 注释的任何方法之前启动。它在测试完成后终止,并且所有带有 @After 注释的方法都完成了。要在测试逻辑中访问被测活动,请向 ActivityScenarioRule.getScenario().onActivity() 提供可运行的回调。

为了解决这个问题,您需要在尝试启动活动之前WorkManager在测试中初始化。WorkManagerTestInitHelper

为此,您应该避免使用ActivityScenarioRuleActivityScenario改为使用,您可以执行以下操作:

@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
class LoginTest {
    private lateinit var scenario: ActivityScenario<MainActivity>

    @get:Rule
    var hiltRule = HiltAndroidRule(this)

    @Before
    fun before() {
        val context = InstrumentationRegistry.getInstrumentation().targetContext
        val config = Configuration.Builder()
            .setMinimumLoggingLevel(Log.DEBUG)
            .setExecutor(SynchronousExecutor())
            .build()
        WorkManagerTestInitHelper.initializeTestWorkManager(context, config)

        scenario = launchActivity()
    }

    @Test
    fun test() {
        scenario.moveToState(Lifecycle.State.CREATED).onActivity { 
             activity -> // do some test with the activity
        }
    }
}
于 2020-11-03T11:38:28.630 回答