【问题标题】:Robolectric (Android): Using ShadowLocationManager ? Is it configurable?Robolectric (Android):使用 ShadowLocationManager ?是否可配置?
【发布时间】:2025-12-10 05:25:02
【问题描述】:

到目前为止,我一直在非常成功地使用 Robolectric。我有一个获取位置管理器的活动。现在根据文档,robolectric 框架包含一个名为“ShadowLocationManager”的影子类来制作一种模拟。

我的问题真的是,我如何控制这个模拟,我可以控制返回什么?如果有怎么办?

或者我必须创建我的“OWN”影子类并实现“ShadowLocationManager”。

我一直在搜索文档,但找不到任何东西来确认我在问什么。

如果 robolectric 确实包含位置管理器的影子,我如何控制启用哪些提供程序?如果一个已经存在并且可以配置和控制的影子类,我不想实现自己的影子类。

【问题讨论】:

    标签: android unit-testing mocking robolectric


    【解决方案1】:

    Robolectric 中的影子类是各种 Android 类的替代品,只能根据其实现的功能进行更改。

    看看the source for ShadowLocationManager,你有一些方法可以用来调整假货的行为:

        public void setProviderEnabled(String provider, boolean isEnabled);
        public void setProviderEnabled(String provider, boolean isEnabled, List<Criteria> criteria);
        public boolean setBestProvider(String provider, boolean enabled);
        public boolean setBestProvider(String provider, boolean enabled, List<Criteria> criteria);
        public void setLastKnownLocation(String provider, Location location);
    

    您可以通过以下方式获取 LocationManager 的影子实例:

    LocationManager instanceOfLocationManager = Robolectric.newInstanceOf(LocationManager.class);
    ShadowLocationManager slm = Robolectric.shadowOf(instanceOfLocationManager);
    

    注意:在示例中,我使用 Robolectric 创建LocationManager 的实例。根据您的测试设置,此实例可能来自您的注入框架或直接来自调用Context.getSystemService(..)。底线是,确保测试中的实例与正在测试的代码使用的实例相同。

    【讨论】:

    • 啊,好吧,一旦我有了 shadown 的实例,我就可以用 setProviderEnabled 来改变它?这太好了,这就是我想要的,但我是否将它传回或告诉 robolectric 使用我的实例,surley 它不是自动的......我必须将实例发送到 robolectric 才能使用它,不是吗?
    • 现在它开始陷入 :-) 所以我可以创建一个实例,但不确定如何将该实例发送到 Robolectric 以便它使用我的影子/模拟
    • 对不起,如果我在我的测试班,我从哪里获得 instanceOfLocationManager?
    • @Martin - 在示例中添加了更多内容。另外:是的,它是自动的,阴影实例将由 Robolectric 创建。影子实例存储为LocationManager 实例的一部分。
    • 你会得到一个类似LocationManager = (LocationManager) Robolectric.application.getSystemService(Application.LOCATION_SERVICE);的位置管理器实例。如果您使用的是 DI 框架或其他东西,它可能会变得更复杂一些。