Marshmallow PermissionHelper 的 Android Robolectric 单元测试

Android Robolectric unit test for Marshmallow PermissionHelper

提问人:muetzenflo 提问时间:1/27/2016 最后编辑:muetzenflo 更新时间:6/20/2019 访问量:8982

问:

我想学习 Robolectric,以便将其用于 Android Marshmallow 应用程序上的单元测试。我写了一些方法,使权限处理更容易一些。为了开始使用此类的单元测试,我正在尝试测试最简单的方法:PermissionHelper

public static boolean hasPermissions(Activity activity, String[] permissions) {
    for (String permission : permissions) {
        int status = ActivityCompat.checkSelfPermission(activity, permission);
        if (status == PackageManager.PERMISSION_DENIED) {
            return false;
        }
    }
    return true;
}

这是我到目前为止编写的 Robolectric 测试:

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class PermissionHelperTest {

    private PermissionHelper permissionHelper;
    private ShadowApplication application;

    @Before
    public void setup() {
        PictureActivity activity = Robolectric.buildActivity(PictureActivity.class).get();
        permissionHelper = new PermissionHelper(activity, activity, 1);
        application = new ShadowApplication();
    }

    @Test
    public void testHasPermission() throws Exception {
        String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        boolean hasPermissions = permissionHelper.hasPermissions(permissions);
        Assert.assertEquals(false, hasPermissions);

        application.grantPermissions(permissions);
        hasPermissions = permissionHelper.hasPermissions(permissions);
        Assert.assertEquals(true, hasPermissions);
    }
}

第一个 Assert 有效(未授予权限)。但是,在通过 ShadowApplication 授予所有权限后,它们仍然在下一个 Assert 中被拒绝。

我认为创建的 with 没有使用 ShadowApplication 进行权限检查。但不给我打电话。我该如何测试?PictureActivityRobolectric.buildActivity()PictureActivity.getApplication()ShadowApplicationgrantPermissions

我是 Android 上的 Robolectric 和单元测试的新手......因此,如果有任何其他框架可以使这更容易/可能:我愿意接受建议。

Android 单元测试 robolectric android-permissions android-6.0-marshmallow

评论


答:

13赞 Gent Ahmeti 2/8/2016 #1

你的问题是你正在使用不同的应用程序来授予权限,而不是你自己的权限。

取而代之的是:

application = new ShadowApplication();

您应该了解应用程序的影子,如下所示:

application = Shadows.shadowOf(activity.getApplication());

评论

0赞 muetzenflo 2/8/2016
是的,这奏效了!谢谢。更改后,我收到了另一个错误,即AndroidHttpClient丢失,但这是此处讨论的简单修复方法:github.com/robolectric/robolectric/issues/1862
17赞 JavierSP1209 6/8/2016 #2

与其使用我使用的接收上下文,不如发送上下文的模拟并返回授予的权限,这对我们有用:ActivityCompatContextCompat.checkSelfPermission()

而不是:

ActivityCompat.checkSelfPermission(activity, permission);

ContextCompat.checkSelfPermission(context, permission);

然后,在文本中,您可以直接将模拟发送到您的方法,并将结果存根为:hasPermissions

Context context = mock(Context.class);
when(context.checkPermission(eq("YOUR_PERMISSION"),anyInt(),anyInt())).thenReturn(
    PackageManager.PERMISSION_GRANTED);

评论

0赞 IgorGanapolsky 8/15/2017
这是 Mockito 的一部分,还是 Robolectric 的一部分
1赞 JavierSP1209 8/15/2017
哪一部分? 是 Android 支持包的一部分,其余的都是常规的 mockitoContextCompat
14赞 Руслан Ягупов 6/18/2019 #3

从 Robolectric 4.2 开始,您可以使用:

Application application = ApplicationProvider.getApplicationContext();
ShadowApplication app = Shadows.shadowOf(application);
app.grantPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE);