问题
I wanna learn Robolectric to use it for unit tests on an Android Marshmallow app. I wrote a PermissionHelper
with some methods to make permission handling a bit easier. To get started with unit tests for this class, I am trying to test the most simple method:
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;
}
Here is the Robolectric test that I wrote so far:
@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);
}
}
The first Assert works (no permission granted). But after granting all permissions via the ShadowApplication they are still denied in the next Assert.
I think that the PictureActivity
created with Robolectric.buildActivity()
is not using the ShadowApplication for the permission checks. But PictureActivity.getApplication()
does not give me a ShadowApplication
to call grantPermissions
on. How can I test this?
I am new to Robolectric and unit testing on Android...so if there is any other framework that makes this easier/possible: I am open for suggestions.
回答1:
From Robolectric 4.2 you can use:
Application application = ApplicationProvider.getApplicationContext();
ShadowApplication app = Shadows.shadowOf(application);
app.grantPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE);
回答2:
Instead of using ActivityCompat
I'm using ContextCompat.checkSelfPermission()
which receives a context, so send a mock of the context and return permission granted, this is work for us:
Instead of:
ActivityCompat.checkSelfPermission(activity, permission);
use
ContextCompat.checkSelfPermission(context, permission);
then in your text you can send a mock directly to your hasPermissions
method and stub the result as:
Context context = mock(Context.class);
when(context.checkPermission(eq("YOUR_PERMISSION"),anyInt(),anyInt())).thenReturn(
PackageManager.PERMISSION_GRANTED);
回答3:
Your problem is that you're using a different application to grant permissions, not your own.
Instead of this:
application = new ShadowApplication();
you should get a shadow of your application, like this:
application = Shadows.shadowOf(activity.getApplication());
来源:https://stackoverflow.com/questions/35031301/android-robolectric-unit-test-for-marshmallow-permissionhelper