如何在BroadcastReceiver中测试对PendingIntent.getBroadcast(...)的静态调用

帕斯卡尔·扎格(Pascal Zaugg)

我真的在这个问题上迷路了。我确实构建了以下BroadcastReceiver

package ch.pas.smslistenerservice.receiver;

import ch.pas.smslistenerservice.service.SMSListenerService;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class Resend extends BroadcastReceiver {
    private static String logTag = "ch.pas.smslistenerservice.resend";

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { return; }

        Log.i(logTag, "Resend received");

        PendingIntent pIntent = getPendingIntent(context);
        if(pIntent != null) { 
            Log.d(logTag, "Canceling intent");
            pIntent.cancel(); 
        }

        Log.d(logTag, "Starting service...");
        Intent serviceIntent = new Intent(context, SMSListenerService.class);
        serviceIntent.putExtra(SMSListenerService.EXTRA_TYPE, SMSListenerService.TYPE_RESEND);
        context.startService(serviceIntent);
    }

    protected PendingIntent getPendingIntent(Context context) {
        return PendingIntent.getBroadcast(context, 0, 
                new Intent("ch.pas.smslistenerservice.RESEND"), 
                PendingIntent.FLAG_NO_CREATE);
    }
}

我尝试测试if语句,并且很想测试PendingIntent对象是否获得取消消息。

if(pIntent != null) { 
    Log.d(logTag, "Canceling intent");
    pIntent.cancel(); 
 }

我试过的是:

  1. 分解出检索待定意图的方法,然后使用mockito模拟返回的PendingIntent。由于Mockito无法模拟最终课程(如PendingIntent),因此无法解决。
  2. 使用PowerMock模拟静态调用PendingIntent.getBroadcast(...),但是由于PowerMock无法在Android上运行而无法解决,并且如果我在JVM上运行此测试,则会收到带有“ Stub!”的RuntimeException!因为我扩展了仅适用于Android的BroadcastReceiver。

我知道在那种情况下测试它没有太大意义,因为在if语句中没有太多逻辑可以测试,但是如果还有更多逻辑可以测试呢?

帕斯卡尔·扎格(Pascal Zaugg)

通过组合使用PowerMock,Mockito和Robolectric(<=这是丢失的变量)解决了此问题。使用Robolectric屏蔽(模拟)对PendingIntent.getBroadcast(...)的静态调用,并注入模拟的PendingIntent。

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.powermock.api.mockito.PowerMockito;
import org.robolectric.*;
import org.robolectric.annotation.Config;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

import ch.pas.smslistenerservice.receiver.Resend;
import ch.pas.smslistenerservice.service.SMSListenerService;

@Config(shadows=CustomShadowPendingIntent.class)
@RunWith(RobolectricTestRunner.class)
public class ResendTest {
    Resend receiver;
    Context context;
    PendingIntent pendingIntent;

    @Before
    public void before() {
        context = Mockito.mock(Context.class);
        pendingIntent = PowerMockito.mock(PendingIntent.class);
        receiver = new Resend();
    }

    @Test
    public void testStartServiceWithoutExistingPendingIntent() {
        CustomShadowPendingIntent.setPendingIntent(null);

        Intent intent = new Intent("ch.pas.smslistenerservice.RESEND");
        receiver.onReceive(context, intent);      

        ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
        verify(context).startService(argument.capture());
        Intent capturedIntent = argument.getValue();
        assertFalse(-1 == capturedIntent.getIntExtra(SMSListenerService.EXTRA_TYPE, -1));
        assertEquals(SMSListenerService.TYPE_RESEND, 
                capturedIntent.getIntExtra(SMSListenerService.EXTRA_TYPE, -1));
    }

    @Test
    public void testStartServiceWithExistingPendingIntent() {
        CustomShadowPendingIntent.setPendingIntent(pendingIntent);

        Intent intent = new Intent("ch.pas.smslistenerservice.RESEND");
        receiver.onReceive(context, intent);      

        verify(pendingIntent, times(1)).cancel();

        ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
        verify(context).startService(argument.capture());
        Intent capturedIntent = argument.getValue();
        assertFalse(-1 == capturedIntent.getIntExtra(SMSListenerService.EXTRA_TYPE, -1));
        assertEquals(SMSListenerService.TYPE_RESEND, 
                capturedIntent.getIntExtra(SMSListenerService.EXTRA_TYPE, -1));
    }
}

以及阴影中的PendingIntent:

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import android.app.PendingIntent;

@Implements(PendingIntent.class)
public class CustomShadowPendingIntent 
    extends org.robolectric.shadows.ShadowPendingIntent {
    private static PendingIntent pendingIntentMock;

    public static void setPendingIntent(PendingIntent intent) {
        pendingIntentMock = intent;
    }

    @Implementation
    public static PendingIntent getBroadcast(android.content.Context context, 
            int requestCode, android.content.Intent intent, int flags) {
        return pendingIntentMock;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在BroadcastReceiver中测试对PendingIntent.getBroadcast(...)的静态调用

来自分类Dev

PendingIntent.getBroadcast无法解析

来自分类Dev

PendingIntent.getBroadcast无法解析

来自分类Dev

Automatically assign requestCodes to PendingIntent.getBroadcast (using AlarmManager)

来自分类Dev

如何在Android中测试静态方法调用?

来自分类Dev

自动将requestCodes分配给PendingIntent.getBroadcast(使用AlarmManager)

来自分类Dev

PendingIntent.getBroadcast() 总是用 FLAG_UPDATE_CURRENT 返回 null

来自分类Dev

在C ++中调用静态链接的静态方法

来自分类Dev

在静态方法中调用非静态方法

来自分类Dev

调用C静态测试的构造

来自分类Dev

调用C静态测试的构造

来自分类Dev

在php中调用静态属性

来自分类Dev

在静态类中如何调用该方法

来自分类Dev

如何在C ++模板中调用静态数组的解释器?

来自分类Dev

如何在expressjs中调用静态html页面

来自分类Dev

如何在Magento的产品说明中调用特定的静态块?

来自分类Dev

如何在Swift中调用协议提供的静态方法

来自分类Dev

如何在Symfony的YAML配置中调用静态方法?

来自分类Dev

如何在TypeScript中调用类型参数的静态方法

来自分类Dev

如何在Kendo Grid列中调用静态方法

来自分类Dev

如何在SwingWorker的doInBackground()中停止调用的静态方法

来自分类Dev

如何在C ++中异步调用静态方法?

来自分类Dev

如何在结构中调用静态无参数构造函数?

来自分类Dev

如何在TypeScript中调用类型参数的静态方法

来自分类Dev

如何在python中通过引用调用静态方法

来自分类Dev

如何在类中调用静态成员(这是普通类)

来自分类Dev

如何在tpl文件中调用tcpdf非静态方法

来自分类Dev

Java /静态模拟中的静态调用中的对象

来自分类Dev

如何从父级的静态方法调用子级的静态方法?

Related 相关文章

  1. 1

    如何在BroadcastReceiver中测试对PendingIntent.getBroadcast(...)的静态调用

  2. 2

    PendingIntent.getBroadcast无法解析

  3. 3

    PendingIntent.getBroadcast无法解析

  4. 4

    Automatically assign requestCodes to PendingIntent.getBroadcast (using AlarmManager)

  5. 5

    如何在Android中测试静态方法调用?

  6. 6

    自动将requestCodes分配给PendingIntent.getBroadcast(使用AlarmManager)

  7. 7

    PendingIntent.getBroadcast() 总是用 FLAG_UPDATE_CURRENT 返回 null

  8. 8

    在C ++中调用静态链接的静态方法

  9. 9

    在静态方法中调用非静态方法

  10. 10

    调用C静态测试的构造

  11. 11

    调用C静态测试的构造

  12. 12

    在php中调用静态属性

  13. 13

    在静态类中如何调用该方法

  14. 14

    如何在C ++模板中调用静态数组的解释器?

  15. 15

    如何在expressjs中调用静态html页面

  16. 16

    如何在Magento的产品说明中调用特定的静态块?

  17. 17

    如何在Swift中调用协议提供的静态方法

  18. 18

    如何在Symfony的YAML配置中调用静态方法?

  19. 19

    如何在TypeScript中调用类型参数的静态方法

  20. 20

    如何在Kendo Grid列中调用静态方法

  21. 21

    如何在SwingWorker的doInBackground()中停止调用的静态方法

  22. 22

    如何在C ++中异步调用静态方法?

  23. 23

    如何在结构中调用静态无参数构造函数?

  24. 24

    如何在TypeScript中调用类型参数的静态方法

  25. 25

    如何在python中通过引用调用静态方法

  26. 26

    如何在类中调用静态成员(这是普通类)

  27. 27

    如何在tpl文件中调用tcpdf非静态方法

  28. 28

    Java /静态模拟中的静态调用中的对象

  29. 29

    如何从父级的静态方法调用子级的静态方法?

热门标签

归档