Reputation: 19826
I am trying to use Robolectric to test my Android application but have come across a testing issue I can't get my head around.
I am testing an Activity which extends my BaseActivity class and uses RxAndroid, that class looks like this:
public abstract class BaseActivity extends AppCompatActivity {
protected final SharedService sharedService = MyApplication.getInstance().getSharedService();
protected Activity getActivity() {
return this;
}
}
As you can see it gets a sharedService object from my Application base class.
In my Activity I then reference this code as follows:
//...
Subscription s = sharedService.login(params)
.compose(ObservableUtils.<JsonObject>applySchedulers())
.subscribe(new Action1<JsonObject>() {
@Override
public void call(JsonObject jsonObject) {
//...
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
//...
}
});
subscriptions.add(s);
//..
So the Activity directly references the sharedService variable from the BaseActivity to access it and call a method on the SharedService Object. It uses RxAndroid to get an observable.
The code in the Retrofit call is as follows:
@POST("/login")
Observable<JsonObject> login(
@Body JsonObject body) ;
The problem is when I come to test using Robolectric I get a null pointer exception in the Activity where when the RxAndroid code is called.
My test is as follows:
@Config(constants = BuildConfig.class)
@RunWith(TestRunner.class)
public class MyActivityTest{
@Mock
private SharedService mockSharedService;
@Before
public void setup() {
// Convenience method to run Activity through the Activity Lifecycle methods:
// onCreate(...) => onStart() => onPostCreate(...) => onResume()
MockitoAnnotations.initMocks(this);
TestMyApplication testMyApp = (TestMyApplication) TestCompanionApplication.getInstance();
testMyApp.setSharedService(this.mockSharedService); //Set our Mocked application class to use our mocked API
//Build our activity using Robolectric
ActivityController<MyActivity> controller = Robolectric.buildActivity(MyActivity.class);
activity = controller.get();
controller.create(); //Create out Activity
//..Get views
}
@Test
public void testService(){
btnTest.click(); //This fires the service call
Mockito.verify(this.mockSharedService).login((JsonObject) Mockito.any());
}
When I run this test I get the NullPointerException.
So I know that I somehow need to get the Activity to use the mocked API that I have set on the TestMyApplication class, but since the BaseActivity creates a variable that holds this and then my other Activities reference this how do I do this with Robolectric?
Upvotes: 1
Views: 258
Reputation: 20130
It is quite easy to fix:
when(mockSharedService.login(any())).thenReturn(Observable.just(new JsonObject()));
But it will probably fail later where you're trying to process received json
.
Upvotes: 1