使用Robolectric为粘性广播自定义上下文

3

我想要测试我的BroadcastReceiver,它依赖于黏性广播,并借助Robolectric进行测试。默认情况下,Robolectric不支持黏性广播,因此我创建了自定义的Context以使得黏性广播能够正常工作,代码如下:

public class MyContext extends MockContext {

    public MyContext() {
        super();
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        if(receiver == null) { // A sticky broadcast was requested
            Intent request = new Intent();
            String action = filter.getAction(0);

            if(Intent.ACTION_BATTERY_CHANGED.equals(action)) {
                request.putExtra(BatteryManager.EXTRA_PLUGGED, 1);
            } else if(Intent.ACTION_HEADSET_PLUG.equals(action)) {
                request.putExtra("state", 1); 
            }

            return request;
        }

        return super.registerReceiver(receiver, filter);
    }
}

我遇到的问题是必须使用RuntimeEnvironment.application.getApplicationContext来获取有效的Context对象(我尝试调用自定义Context的构造函数,但不起作用)。那么我该如何获取有效实例的自定义Context或者在Robolectric中这是否可能呢? 编辑:以下是我的测试代码和广播接收器代码:
@Before
public void setup() {
    context = RuntimeEnvironment.application.getApplicationContext();
    receiver = new MyBroadcastReceiver(); // Create Receiver
}

@After
public void finish() {
    context.unregisterReceiver(receiver);
}

@Test
public void validateUsbChargingChange() {
    IntentFilter filter = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
    context.registerReceiver(receiver, filter);

    // Simmulate SocketCharging by sending the corresponding Intent
    Intent chargingChange = new Intent("android.intent.action.ACTION_POWER_CONNECTED");
    RuntimeEnvironment.application.sendBroadcast(chargingChange);

    validatePreferences();
}

BroadcastReceiver:

@Override
public void onReceive(Context context, Intent intent) {
    IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent chargingIntent = appContext.registerReceiver(null, iFilter); // sticky
    int pluggedState = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

    boolean usbCharge = (pluggedState == BatteryManager.BATTERY_PLUGGED_USB);
    if(usbCharge) {  /* Write values to preferences */  }
}

1
你使用的Robolectric版本是什么?在查看ShadowApplication时,我发现代码似乎真的想处理粘性意图。 https://github.com/robolectric/robolectric/blame/master/robolectric-shadows/shadows-core/src/main/java/org/robolectric/shadows/ShadowApplication.java#L552 - Eric O'Connell
哦,对了...我正在使用Robolectric版本3.3.1。 - Cilenco
1
你的测试看起来是什么样子? - azizbekian
1个回答

0

你可以在测试类构造函数中显式发送StickBroadcast,就像下面这样

@RunWith(RobolectricTestRunner.class)
public class BatterySettingActivityTest {
    {
        ApplicationProvider.getApplicationContext().sendStickyBroadcast(new Intent(Intent.ACTION_BATTERY_CHANGED).putExtra(BatteryManager.EXTRA_LEVEL, 75).putExtra(BatteryManager.EXTRA_PLUGGED, 0));
    }

    @Rule
    public ActivityScenarioRule<BatterySettingActivity> activityScenarioRule = new ActivityScenarioRule<>(BatterySettingActivity.class);


    @Test
    public void testStickBroadcast() {
        activityScenarioRule.getScenario().onActivity(activity -> {
            System.out.println("intentForStickyBroadcast=" + activity.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
        });
    }
}

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