用JUnit测试一个请求

用JUnit测试一个请求,junit,kotlin,rx-java,Junit,Kotlin,Rx Java,我想用JUnit测试这样的请求,但是RxUtils.applySchedulersAndErrorMapper返回null。有没有可能测试一下 override fun onContinueClicked(phoneNumber: String) { mView.showLoading() mUserService.checkUserApprovedStatus(phoneNumber) .compose(RxUtils.applySchedule

我想用JUnit测试这样的请求,但是RxUtils.applySchedulersAndErrorMapper返回null。有没有可能测试一下

override fun onContinueClicked(phoneNumber: String) {
    mView.showLoading()
    mUserService.checkUserApprovedStatus(phoneNumber)
                .compose(RxUtils.applySchedulersAndErrorMapper())
                .subscribe({ response ->
                    //Success
                }, { error ->
                    //Error
                })
}
这里是我为presenter设置presenter和mUserService的地方

@Mock
private PhoneContract.View view;

@Mock
private UserService userService;

  @Before
public void setup() {
    presenter = new PhonePresenter(this.view);
    presenter.mUserService = userService;
}
这是测试方法

 @Test
public void onContinueClicked_SendJustNumbers() {
    String phoneNumber = "(01234567890)";
    // when
    presenter.onContinueClicked(phoneNumber);
    // then
    verify(view, times(1)).showLoading();
}
这是RXUtils类:

class RxUtils {
    companion object {

        @SuppressLint("CheckResult")
        fun <E> applySchedulersAndErrorMapper(): ObservableTransformer<E, E> {
            return ObservableTransformer { o ->
                o.flatMap(Function<E, ObservableSource<E>> { element ->
                    val genericResponse = element as GenericResponse<*>
                    @Suppress("UNCHECKED_CAST")
                    return@Function Observable.just(genericResponse as E)
                }).onErrorResumeNext(Function<Throwable, ObservableSource<E>> { t ->
                    if (t is ApiException) {
                        return@Function Observable.error(t)
                    }
                    var genericResponse: GenericResponse<*>? = null

                    return@Function Observable.error(ApiException(t.message ?: "", genericResponse?.result ?: Result()))
                })
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeOn(Schedulers.io())
            }
        }
    }
}

如果它与SDK相关,那么它可能无法在单元测试中工作。您没有包括您的导入,所以不可能一目了然,但根据经验,我知道您不能在单元测试中使用它

AndroidSchedulers.mainThread()
你需要用,比如说,调度员,蹦床来代替它

如何为测试设置自定义计划程序的示例

注意,这只是一个示例,还有其他有效的解决方案

class RxUtils {
companion object {

    // add this
    @VisibleForTesting var mainScheduler = AndroidSchedulers.mainThread()
    @VisibleForTesting var ioScheduler = Schedulers.io()

    @SuppressLint("CheckResult")
    fun <E> applySchedulersAndErrorMapper(): ObservableTransformer<E, E> {
        return ObservableTransformer { o ->
            o.flatMap(Function<E, ObservableSource<E>> { element ->
                val genericResponse = element as GenericResponse<*>
                @Suppress("UNCHECKED_CAST")
                return@Function Observable.just(genericResponse as E)
            }).onErrorResumeNext(Function<Throwable, ObservableSource<E>> { t ->
                if (t is ApiException) {
                    return@Function Observable.error(t)
                }
                var genericResponse: GenericResponse<*>? = null

                return@Function Observable.error(ApiException(t.message ?: "", genericResponse?.result ?: Result()))
            })
                    .observeOn(mainScheduler)
                    .subscribeOn(ioScheduler)
        }
    }
}
编辑以响应更新的帖子,并提供更多关于测试的信息

首先,您应该发布更多的代码。要把它一点一滴地从你身上抽出来是令人沮丧的。无论如何您具有以下功能:

@Mock
private UserService userService;
当然,这会创建一个模拟用户服务,但它不会存根任何东西。当您调用userService.anyfunctionall时,默认情况下它将返回null。这是你的NPE。你必须把它存根。例如:

Mockito.when(userService.anyFunctionAtAll()).thenReturn(somePredeterminedValue)

有关更多信息,请参阅Mockito。

可以模拟RxUtils?模拟静态方法既不容易,也不推荐。相反,请使用一些间接方法,允许您在测试环境中指定不同的调度程序。您能给我一个示例吗?仍然是空点。Composer Xutils.ApplySchedulers的例外您仍然没有包含测试代码。您使用PowerMock的目的是什么?
@Mock
private UserService userService;
Mockito.when(userService.anyFunctionAtAll()).thenReturn(somePredeterminedValue)