Robolectric未调用Application.onCreate()致SDK上下文为空的排查与解决
问题原因与解决方案
为什么会出现这个问题?
Robolectric默认情况下不会自动使用你项目中自定义的App.Application类——它会创建一个简化的测试用Application实例来运行测试。这就导致你写在App.Application.onCreate()里的SDK上下文初始化代码根本没被执行,自然拿不到Context。
另外,你测试代码里的逻辑依赖BuildConfig.FLAVOR.equals("dev"),如果测试运行的不是dev flavor,这段判断会跳过,也可能让你误以为Context为空(不过从描述来看,核心问题还是onCreate没触发)。
解决方法分两种场景:
1. 让Robolectric触发你的自定义Application的onCreate
直接在测试类上通过@Config注解指定你的Application类,Robolectric就会正确初始化它并执行onCreate方法:
@RunWith(RobolectricTestRunner.class) @Config(application = App.Application.class, flavors = {"dev"}) // 指定你的Application和dev flavor public class CallTest { @Before public void setUp() throws Exception {} @Test public void connectToSocketTest() { if (BuildConfig.FLAVOR.equals("dev")) { Context context = SDK1.getInstance().getContext(); assertNotNull(context); // 后续测试逻辑 } } }
注意:如果是Robolectric 4.5+版本,也可以用@RunWith(AndroidJUnit4.class),但@Config的配置逻辑是一致的。
2. 手动初始化SDK的上下文(更灵活的测试控制)
如果你不想依赖Application的生命周期(比如测试时想隔离生产初始化逻辑),可以在@Before方法里手动给SDK设置Context:
@RunWith(RobolectricTestRunner.class) @Config(flavors = {"dev"}) public class CallTest { @Before public void setUp() throws Exception { // 获取Robolectric提供的测试Application上下文 Context testContext = RuntimeEnvironment.application; // 手动给SDK1单例设置上下文 SDK1.getInstance().setContext(testContext); } @Test public void connectToSocketTest() { if (BuildConfig.FLAVOR.equals("dev")) { Context context = SDK1.getInstance().getContext(); assertNotNull(context); // 后续测试逻辑 } } }
这种方式更贴合单元测试的隔离原则,避免生产代码的初始化逻辑干扰测试结果。
额外注意点
- 确保你的测试运行配置里确实选择了dev flavor,否则
BuildConfig.FLAVOR不会匹配,测试逻辑会被跳过。 - 如果你的SDK单例是懒加载的,要确保在获取实例前已经设置了Context(或者修改SDK的初始化逻辑,允许在获取实例后设置Context)。
内容的提问来源于stack exchange,提问作者Tlaloc-ES
相关产品推荐
相关产品推荐

