I have an Activity
public class MyActivity extends ActionBarActivity {
public int i;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
i = getSomeInt();
}
protected int getSomeInt() {
return 1; // here can be an api-request
}
}
and i want to test it with robolectric 3.0
and mockito
.
But i need to mock getSomeInt()
methiod.
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class)
public class MyActivityTest {
private MyActivity mActivity;
@Before
public void setUp() {
mActivity = spy(Robolectric.buildActivity(MyActivity.class).create().get());
doReturn(2).when(mActivity).getSomeInt(); //but it is already after onCreate!
}
@Test
public void testGetInt() {
assertEquals(2, mActivity.i); //error
}
}
Is it possible to use already mocked method by creating of activity?
EDIT
i have tried
@Before
public void setUp() {
ActivityController<MyActivity> co = Robolectric.buildActivity(MyActivity.class);
mActivity = spy(co.get());
doReturn(2).when(mActivity).getSomeInt();
co.create();
}
but i seems, that onCreate
was not called by mActivity
assertEquals(2, mActivity.i);
//gives the result:
java.lang.AssertionError:
Expected :2
Actual :0
thanks Eugen for the consideration, it doesnt work, because create
call on controller, that operates with activity that is not spied
Mockito only mocks an object. But it cannot modify the activity reference of ActivityController
.
So I try to isolate the function and pass it to activity before creating.
Four steps:
Isolate the functions as a member of a new class
public class SomeInt{
public int get() {
return 1; // here can be an api-request
}
}
Use the functions by an object in MyActivity
public class MyActivity extends ActionBarActivity {
SomeInt someInt;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
i = someInt.get();
}
}
Make an API to set the object someInt
in test
use ShadowActivity
-- I recommanded this, separating the code and the test
@Implements(MyActivity.class)
public class ShadowMyActivity extends ShadowActivity
{
@RealObject
private MyActivity myActivity;
@Implementation
public void setForMockito(SomeInt someint)
{
myActivity.someint = someint;
}
}
or let the object public
public SomeInt someInt;
or make a public setter for the object in MyActivity
Mock in test
If use ShadowActivity
@Config(constants = BuildConfig.class shadows = ShadowMyActivity.class)
Class TestMyActivity {
@Before
public void setUp()
{
SomeInt someIntMock = mock(SomeInt.class);
ActivityController<MyActivity> co = Robolectric.buildActivity(MyActivity.class);
mActivity.setForMockito(someIntMock);
doReturn(2).when(someIntMock).get();
co.create();
// verify here or in tearDown
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With