Robolectric中的getSystemService返回具有null Context的对象

时间:2014-09-24 15:51:34

标签: android robolectric

在我的活动中onCreate我有:

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

使用Robolectric测试活动时,我用

创建它
ActivityController<MainActivity> controller = Robolectric.buildActivity(MainActivity.class);
MainActivity activity = controller.attach().create().get();

然后创建AudioManager,但mContext = null在调用NullPointerException时导致registerMediaButtonEventReceiver,因为该框架方法在内部使用了上下文。

有没有办法确保使用AudioManager创建Context

4 个答案:

答案 0 :(得分:5)

我玩了一下这个,我实际上认为目前答案是没有,没有办法。

现在,如果目的是在创建活动时避免使用NPE,那么您可以通过在测试中执行类似的操作来模拟AudioManager,对于Robolectric版本&lt; 3:

    AudioManager mockManager= Mockito.mock(AudioManager.class);
    Application application = (Application) Robolectric.getShadowApplication().getApplicationContext();
    ShadowContextImpl shadowContext = (ShadowContextImpl) Robolectric.shadowOf(application.getBaseContext());
    shadowContext.setSystemService(Context.AUDIO_SERVICE, mockManager);

另一个变体可能是create your own ShadowAudioManager处理registerMediaButtonEventReceiver或使用正确的上下文进行初始化,因为current one没有这样做,但我实际上没有尝试过。

答案 1 :(得分:3)

使用Robolectric 3+:

AudioManager mockManager= Mockito.mock(AudioManager.class);
Application application = (Application) Robolectric.getShadowApplication().getApplicationContext();
ShadowContextImpl shadowContext = (ShadowContextImpl) Shadows.shadowOf(application.getBaseContext());
shadowContext.setSystemService(Context.AUDIO_SERVICE, mockManager);

答案 2 :(得分:2)

为了避免类似的NPE崩溃,我添加了

 @Config(emulateSdk = 18, shadows = {ShadowAudioManager.class}) 

在包含测试的类中!

答案 3 :(得分:1)

当调用 ConnectivityManager 时,我必须模拟 NetworkInfo 以返回一个空的 getActiveNetworkInfo() 对象,使用 Roboelectric 4.4,您可以这样做:

val context: Context = ApplicationProvider.getApplicationContext()
val spiedConnManager = spy(context.getSystemService(Context.CONNECTIVITY_SERVICE) 
                           as ConnectivityManager)
//set the service to return what you want, 
//in my case I set the connectivity manager to return null for activeNetworkInfo
doReturn(null).`when`(spiedConnManager).activeNetworkInfo
val shadowApp: ShadowApplication = shadowOf(context as Application)
//setSystemService is deprecated but I did not found a replacement yet
shadowApp.setSystemService(Context.CONNECTIVITY_SERVICE, spiedConnManager)
//perform your asserts HERE

你可以对任何你想要的系统服务使用相同的方法