surga
surga

Reputation: 1661

Mock android.os.BaseBundle without roboelectric

I am trying to do a unit test on this code :

Bundle cidParam(String accountId) {
    Bundle params = new Bundle(1);
    params.putString(Params.CID, accountId);

    return params;
}

This is the unit test :

private void mockBundle(String cid) throws Exception {
    Bundle mBundle = PowerMockito.mock(Bundle.class);
    PowerMockito.doNothing().when((BaseBundle)mBundle).putString(AnalyticsController.Params.CID, cid);
}

However, it always returns:

java.lang.RuntimeException: Method putString in android.os.BaseBundle not mocked.

I know I can use roboelectric to spin up the simulator and call the real bundle. However, it will slow down the unit test. Does anyone know how to mock the Android .os.base? Thank you.

Upvotes: 4

Views: 7087

Answers (5)

hollmannlu
hollmannlu

Reputation: 404

with mockk you could use constructor-mocks (see mockk.io).

example:

mockkConstructor(Bundle::class)
every { anyConstructed<Bundle>().putString(any(), any()) } just runs

Upvotes: 1

sadat
sadat

Reputation: 4342

testOptions {
    unitTests.returnDefaultValues = true
}

worked for me.

Upvotes: 0

Levon Petrosyan
Levon Petrosyan

Reputation: 9625

Try to add this in your build.gradle

android {
    testOptions {
        unitTests {
            unitTests.returnDefaultValues = true
        }
    }
}

Upvotes: 9

surga
surga

Reputation: 1661

I finally get the answer from my friend. The reason is somehow for mocking android class using powermockito the main class need to be set as prepared for test too :

@PrepareForTest({MainClass.class, Bundle.class})

Thank you for the effort @Maciej Kowalski. I'll vote up for your effort since it's on the right direction anyway.

I'm not copy pasting the answer from above, preparing the test for MainClass is the important part.

Upvotes: 0

Maciej Kowalski
Maciej Kowalski

Reputation: 26502

1) Add proper set-up

@RunWith(PowerMockRunner.class)
@PrepareForTest(Bundle.class)
public class MyTest{

2) Use vanilla Mockito for do().when():

Bundle mBundle = PowerMockito.mock(Bundle.class);
    Mockito.doNothing().when(mBundle).putString(AnalyticsController.Params.CID, cid);

3) Use Powermock for whenNew():

PowerMockito.whenNew(Bundle.class)
            .withAnyArguments().thenReturn(mBundle);

Upvotes: 3

Related Questions