【问题标题】:Hilt Instrumentation test with Workmanager not working使用 Workmanager 进行 Hilt Instrumentation 测试不工作
【发布时间】:2020-08-31 13:00:44
【问题描述】:

当我尝试在包含 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.

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

WorkManager 是这样定义的:

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

这是我的测试ATM:

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

}

【问题讨论】:

    标签: android android-espresso android-workmanager android-instrumentation dagger-hilt


    【解决方案1】:

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

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

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

    为此,您应该避免使用ActivityScenarioRule,而是使用ActivityScenario,您可以这样做:

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

    【讨论】:

      【解决方案2】:

      为了利用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...
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-24
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多