用JUnit测试一个请求
我想用JUnit测试这样的请求,但是RxUtils.applySchedulersAndErrorMapper返回null。有没有可能测试一下用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
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)