java - 如何为使用 AndroidSchedulers.mainThread() 的函数编写测试;来自 RxAndroid

标签 java android rx-java rx-android

我在测试方法 shouldFetchMachineSettings() 中收到了一个 NullPointerException。通过调试,我意识到控件没有转到可观察对象的成功回调,也没有启动 Intent 。因此异常(exception)。我意识到问题出在使用 AndroidSchedulers.mainThread(); 但无法找到解决方案。

机器设置.java

public class MachineSettings {

    public static void fetch(final FragmentActivity activity, 
                             MachineService machineService, 
                             final ProgressDialog progressDialog) {
        Observable zippedCalls = Observable.zip(
            machineService.getSettings(), 
            machineService.getInfoAsObservable(), 
            machineService.getSupportedLanguages(), 
            new Func3() {


            @Override
            public Object call(final Object response1, 
                               final Object response2, 
                               final Object response3) {
                return new HashMap<String, Object>() {{
                    put(MACHINE_SETTINGS, response1);
                    put(MACHINE_SETTINGS_INFO, response2);
                    put(MACHINE_SETTINGS_LANGUAGES, response3);
                }};
            }

        });

        zippedCalls.subscribeOn(getNewThread())
                .observeOn(getAndroidSchedulerMainThread())
                .subscribe(onSuccess(activity, progressDialog)
                        , onError(activity, progressDialog));

    }

    public static Scheduler getAndroidSchedulerMainThread() {
        return AndroidSchedulers.mainThread();
    }

    public static Scheduler getNewThread() {
        return Schedulers.newThread();
    }

    private static Action1 onSuccess(final FragmentActivity activity, 
                                     final ProgressDialog progressDialog) {
        return new Action1() {

            @Override
            public void call(Object o) {
                Intent intent = new Intent(activity, MachineSettingsActivity_.class);
            // do some action using object o
            activity.startActivity(intent);
            }
        };
    }

    private static Action1<Throwable> onError(final FragmentActivity activity, 
                                              final ProgressDialog progressDialog) {
        return new Action1<Throwable>() {
            @Override
            public void call(Throwable error) {
                // do some action
            }
        };
    }
}

来自 MachineDetailsFragment.java 的调用

if (item.getItemId() == R.id.action_machine_settings) {
    setupProgressDialog();
    MachineSettings.fetch(getActivity(), machineService, progressDialog);
}

在 MachineDetailsFragmentTest.java 中测试

@Test
public void shouldFetchMachineSettings() {

    MenuItem mockMenuItem = mock(MenuItem.class);
    when(mockMenuItem.getItemId()).thenReturn(R.id.action_machine_settings);

    Map<String, Integer> settings = new HashMap() {{put("privacy", 0);}};
    Map<String, Integer> languages = new HashMap() {{put("index_0", 2);}} ;
    Map<String, String> info = new HashMap()  {{put("version", "1");}};
    Observable<Map<String, Integer>> mockSupportedLanguages = Observable.just(languages);
    Observable<Map<String, Integer>> mockSettings = Observable.just(settings);
    Observable<Map<String, String>> mockInfo = Observable.just(info);

    when(machineService.getSupportedLanguages()).thenReturn(mockSupportedLanguages);
    when(machineService.getSettings()).thenReturn(mockSettings);
    when(machineService.getInfoAsObservable()).thenReturn(mockInfo);

    machineDetailFragment.onOptionsItemSelected(mockMenuItem);

    Intent intent = Shadows.shadowOf(activity).peekNextStartedActivity();
    assertThat(intent.getComponent().getClassName(), 
        is(MachineSettingsActivity_.class.getCanonicalName()));

最佳答案

修改您的类,使其不使用static 方法,并创建一个接受您要使用的两个Scheduler 的构造函数。在您的测试中,您可以使用不同的调度程序,例如 TestSchedulerSchedulers.immediate()

作为一般经验法则:调用其他静态方法(或使用全局状态、单例)的静态方法很难测试。

关于java - 如何为使用 AndroidSchedulers.mainThread() 的函数编写测试;来自 RxAndroid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30881619/

相关文章:

android - 错误 : package rx. android.schedulers 不存在

rx-java - RxJava 2 等同于 Observable.from(Iterable).firstOrDefault?

java - ACM 库简单示例不适用于 jdk 1.7.0_79

java - 检查 ResultSet 是否为 Null,如果不是则获取 int

android - Proguard 与 Roboguice

java - 怎样才能改变自己的形象

java - Response.getWriter() 应该关闭/刷新

java - 如何减小图像尺寸?

android - 警告未经检查的对 'getposition(T)' 的调用

java - RxJava - AbstractOnSubscribe 在 1.1.0 中去了哪里?