Android - Robolectric 使用 RxAndroid 进行测试?
Android - Robolectric testing With RxAndroid?
我正在尝试使用 Robolectric 来测试我的 Android 应用程序,但遇到了一个我无法理解的测试问题。
我正在测试 Activity,它扩展了我的 BaseActivity class 并使用 RxAndroid,class 看起来像这样:
public abstract class BaseActivity extends AppCompatActivity {
protected final SharedService sharedService = MyApplication.getInstance().getSharedService();
protected Activity getActivity() {
return this;
}
}
如您所见,它从我的应用程序库 class 中获取了一个 sharedService 对象。
在我的 Activity 中,我然后按如下方式引用此代码:
//...
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);
//..
因此 Activity 直接从 BaseActivity 引用 sharedService 变量来访问它并调用 SharedService 对象上的方法。它使用 RxAndroid 来获得一个可观察对象。
Retrofit调用中的代码如下:
@POST("/login")
Observable<JsonObject> login(
@Body JsonObject body) ;
问题是当我使用 Robolectric 进行测试时,我在调用 RxAndroid 代码的 Activity 中得到一个空指针异常。
我的测试如下:
@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());
}
当我 运行 这个测试时,我得到了 NullPointerException。
所以我知道我需要以某种方式让 Activity 使用我在 TestMyApplication class 上设置的模拟 API,但是由于 BaseActivity 创建一个变量来保存这个,然后我的其他活动引用这个我如何使用 Robolectric?
修复起来很容易:
when(mockSharedService.login(any())).thenReturn(Observable.just(new JsonObject()));
但它稍后可能会在您尝试处理接收到的地方失败 json
。
我正在尝试使用 Robolectric 来测试我的 Android 应用程序,但遇到了一个我无法理解的测试问题。
我正在测试 Activity,它扩展了我的 BaseActivity class 并使用 RxAndroid,class 看起来像这样:
public abstract class BaseActivity extends AppCompatActivity {
protected final SharedService sharedService = MyApplication.getInstance().getSharedService();
protected Activity getActivity() {
return this;
}
}
如您所见,它从我的应用程序库 class 中获取了一个 sharedService 对象。
在我的 Activity 中,我然后按如下方式引用此代码:
//...
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);
//..
因此 Activity 直接从 BaseActivity 引用 sharedService 变量来访问它并调用 SharedService 对象上的方法。它使用 RxAndroid 来获得一个可观察对象。
Retrofit调用中的代码如下:
@POST("/login")
Observable<JsonObject> login(
@Body JsonObject body) ;
问题是当我使用 Robolectric 进行测试时,我在调用 RxAndroid 代码的 Activity 中得到一个空指针异常。
我的测试如下:
@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());
}
当我 运行 这个测试时,我得到了 NullPointerException。
所以我知道我需要以某种方式让 Activity 使用我在 TestMyApplication class 上设置的模拟 API,但是由于 BaseActivity 创建一个变量来保存这个,然后我的其他活动引用这个我如何使用 Robolectric?
修复起来很容易:
when(mockSharedService.login(any())).thenReturn(Observable.just(new JsonObject()));
但它稍后可能会在您尝试处理接收到的地方失败 json
。