android 单元测试广播接收器?

0aydgbwb  于 2023-03-27  发布在  Android
关注(0)|答案(4)|浏览(169)

这是我的项目中的一个BroadcastReceiver,我希望对其进行单元测试。当用户拨打电话时,它会获取电话号码,并设置一个Intent来启动一个新的Activity,并传递电话号码。

public class OutgoingCallReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context xiContext, Intent xiIntent) 
    {
        if (xiIntent.getAction().equalsIgnoreCase(Intent.ACTION_NEW_OUTGOING_CALL))
        {
            String phoneNum = xiIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

            Intent intent = new Intent(xiContext, MyActivity.class);
            intent.putExtra("phoneNum", phoneNum);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            xiContext.startActivity(intent);
            setResultData(null);
        }
    }
}

到目前为止,我的单元测试看起来像这样:

public class OutgoingCallReceiverTest extends AndroidTestCase
{
    private OutgoingCallReceiver mReceiver;

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();

        mReceiver = new OutgoingCallReceiver();
    }

    public void testStartActivity()
    {
        Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
        intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890");

        mReceiver.onReceive(getContext(), intent);        
    }
}

这将贯穿整个代码,但我希望我的测试能够检查Intent是否已发送,并检查Intent上的电话号码。如何做到这一点?
我还可以测试电话呼叫是否被取消(因为setResultData(null)行)吗?

hrysbysz

hrysbysz1#

corlettk向我指出了Android中的MockContext对象,它可以做到这一点。我已经为它创建了一个子类TestContext,它看起来像这样:

public class TestContext extends MockContext
{
    private List<Intent> mReceivedIntents = new ArrayList<Intent>();

    @Override
    public String getPackageName()
    {
        return "com.mypackage.test";
    }

    @Override
    public void startActivity(Intent xiIntent)
    {
        mReceivedIntents.add(xiIntent);
    }

    public List<Intent> getReceivedIntents()
    {
        return mReceivedIntents;
    }
}

我的测试用例现在看起来像这样:

public class OutgoingCallReceiverTest extends AndroidTestCase
{
    private OutgoingCallReceiver mReceiver;
    private TestContext mContext;

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();

        mReceiver = new OutgoingCallReceiver();
        mContext = new TestContext();
    }

    public void testStartActivity()
    {
        Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
        intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890");

        mReceiver.onReceive(mContext, intent);        
        assertEquals(1, mContext.getReceivedIntents().size());
        assertNull(mReceiver.getResultData());

        Intent receivedIntent = mContext.getReceivedIntents().get(0);
        assertNull(receivedIntent.getAction());
        assertEquals("01234567890", receivedIntent.getStringExtra("phoneNum"));
        assertTrue((receivedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0);
    }
}
zwghvu4y

zwghvu4y2#

马特
听起来你需要模拟一个Context......然后将你的方法转换为接受接口而不是具体的类:public void onReceive(IContext c, IIntent i),只是为了测试的目的。但是Context和Intent类不是你的,是吗?它们是Android的,所以你不能“只是”让它们实现你的接口,所以你必须“ Package ”它们才能暴露你的接口,这是一个相当多的代码,没有太多的收益。非常讨厌!!!
所以我开始怀疑是否有人经历过这一切,并为我们做了艰难的院子......和多田:http://developer.android.com/reference/android/test/mock/package-summary.html
干杯。基思。

mklgxw1f

mklgxw1f3#

自从这个问题被提出以来,mocking框架已经有了很大的发展。使用mockito,你现在不仅可以模拟接口,还可以模拟类。所以我建议通过mocking上下文和使用ArgumentCapture来解决这个问题:

import static org.mockito.Mockito.*;

public class OutgoingCallReceiverTest extends AndroidTestCase {
    private OutgoingCallReceiver mReceiver;
    private Context mContext;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        //To make mockito work
        System.setProperty("dexmaker.dexcache", 
                mContext.getCacheDir().toString());

        mReceiver = new OutgoingCallReceiver();
        mContext = mock(Context.class);
    }

    public void testStartActivity() {
        Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
        intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890");

        mReceiver.onReceive(mContext, intent);
        assertNull(mReceiver.getResultData());

        ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
        verify(mContext, times(1)).startActivity(argument.capture());

        Intent receivedIntent = argument.getValue();         
        assertNull(receivedIntent.getAction());
        assertEquals("01234567890", receivedIntent.getStringExtra("phoneNum"));
        assertTrue((receivedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0);
    }
}
dba5bblo

dba5bblo4#

如果有帮助,请尝试这个方法。没有设备或模拟器的广播接收器单元测试https://stackoverflow.com/a/75854892/15486335

相关问题