【问题标题】:Android - Robolectric testing With RxAndroid?Android - 使用 RxAndroid 进行 Robolectric 测试?
【发布时间】:2016-06-24 09:51:04
【问题描述】:

我正在尝试使用 Robolectric 测试我的 Android 应用程序,但遇到了一个我无法理解的测试问题。

我正在测试一个扩展我的 BaseActivity 类并使用 RxAndroid 的 Activity,该类如下所示:

public abstract class BaseActivity extends AppCompatActivity {
    protected final SharedService sharedService = MyApplication.getInstance().getSharedService();

    protected Activity getActivity() {
        return this;
    }
}

如您所见,它从我的 Application 基类中获取了一个 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 来获取 observable。

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 类上设置的模拟 API,但是由于 BaseActivity 创建了一个变量来保存它,然后我的其他活动引用了这个我该怎么做使用 Robolectric?

【问题讨论】:

  • 为什么你使用JsonObject而不是POJO?这就是 Retrofit 的美丽部分

标签: java android android-activity mockito robolectric


【解决方案1】:

这很容易解决:

when(mockSharedService.login(any())).thenReturn(Observable.just(new JsonObject()));

但稍后在您尝试处理收到的json 时它可能会失败。

【讨论】:

  • 您正在模拟服务,默认情况下,当您开始链接订阅时,它会返回 null。这会导致 NPE。我存根这个调用,所以它返回Observable,一旦订阅就会发出一个JsonObject
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多