Robolectric 4测试在Robolectric.buildActivity().setup()处失败,抛出java.lang.NullPointerException: Bitmap config was null异常。

3
JUnit测试使用Robolectric.buildActivity().setup()在AndroidX和Robolectric 4.3下不一致地失败。通常在测试套件中,前两个这样的测试会失败,但其他测试会通过。
我的公司一直在迁移到AndroidX和Robolectric 4.3,在使我们的测试套件稳定的过程中,我们的一些测试一直失败。添加@LooperMode(PAUSED)以修复“主循环器已排队未执行的可运行项。这可能是测试失败的原因。您可能需要一个shadowOf(getMainLooper()).idle()调用”消息,并停止每个单独的测试都失败,但有些测试仍然不一致地失败。我尝试将Robolectric.buildActivity().setup()替换为ActivityScenario,但错误仍然相同。
这是一个示例代码段,测试将在其中失败,就在Kotlin的初始化阶段。
private val activityController: ActivityController<TestHomeActivity> =
        Robolectric.buildActivity(TestHomeActivity::class.java)
private val homeActivity = activityController.setup().get()

这段文字来自于一个Java测试中的setUp()方法。

    @Before
    public void setUp() throws Exception {
        [...]

        mFragmentActivity = Robolectric.buildActivity(TestHomeActivity.class).setup().get();

    }

大多数情况下,一组测试中只有前两个测试会失败。所有其他测试都将成功初始化或通过setUp()。

以下是我收到的一个错误消息:

java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.

    at org.robolectric.android.internal.AndroidTestEnvironment.checkStateAfterTestFailure(AndroidTestEnvironment.java:470)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:548)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:252)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

这是错误的顶部,但关键在于这里,我相信。 BitmapLruCache 用于处理图像加载。
Caused by: java.lang.NullPointerException: Bitmap config was null.
    at org.robolectric.shadows.ShadowBitmap.getBytesPerPixel(ShadowBitmap.java:674)
    at org.robolectric.shadows.ShadowBitmap.getRowBytes(ShadowBitmap.java:410)
    at org.robolectric.shadows.ShadowBitmap.getAllocationByteCount(ShadowBitmap.java:446)
    at android.graphics.Bitmap.getAllocationByteCount(Bitmap.java)
    at app.base.network.util.BitmapLruCache.putBitmap(BitmapLruCache.java:47)
    at com.android.volley.toolbox.ImageLoader.onGetImageSuccess(ImageLoader.java:304)
    at com.android.volley.toolbox.ImageLoader$2.onResponse(ImageLoader.java:271)
    at com.android.volley.toolbox.ImageLoader$2.onResponse(ImageLoader.java:268)
    at com.android.volley.toolbox.ImageRequest.deliverResponse(ImageRequest.java:257)
    at com.android.volley.toolbox.ImageRequest.deliverResponse(ImageRequest.java:34)
    at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at org.robolectric.shadows.ShadowPausedLooper$IdlingRunnable.run(ShadowPausedLooper.java:308)
    at org.robolectric.shadows.ShadowPausedLooper.executeOnLooper(ShadowPausedLooper.java:273)
    at org.robolectric.shadows.ShadowPausedLooper.idle(ShadowPausedLooper.java:85)
    at org.robolectric.shadows.ShadowPausedLooper.idleIfPaused(ShadowPausedLooper.java:155)
    at org.robolectric.android.controller.ActivityController.visible(ActivityController.java:174)
    at org.robolectric.android.controller.ActivityController.setup(ActivityController.java:251)
    at app.model.viewmodels.ViewModelTestHelper.setUp(ViewModelTestHelper.java:51)
    at app.model.viewmodels.ViewModelUrlGeneratorTest.setUp(ViewModelUrlGeneratorTest.java:70)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:546)
1个回答

1

虽然这不是一个解决为什么会发生这种情况的完整方案,但我有一个解决方法。按照this Robolectric 2.2 issue中的步骤,我创建了这个类:

@Implements(Bitmap.class)
public class CustomBitmapShadow extends ShadowBitmap {
    public CustomBitmapShadow() {
        // can also be some other config value
        setConfig(Bitmap.Config.ARGB_8888);
    }
}

并将此头添加到以前失败的测试中。

@Config(shadows = {CustomBitmapShadow.class})

这并没有解释为什么我在Robolectric 3中不需要这样做,但这是一个解决方案。我并不完全满意,所以我会看看是否有人可以解决问题的根源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接