我想用JUnit用这样的请求测试一个请求,但是RxUtils.applySchedulersAndErrorMapper()返回null。有可能测试吗?
override fun onContinueClicked(phoneNumber: String) {
mView.showLoading()
mUserService.checkUserApprovedStatus(phoneNumber)
.compose(RxUtils.applySchedulersAndErrorMapper())
.subscribe({ response ->
//Success
}, { error ->
//Error
})
}
这里是我为演示者设置演示者和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())
}
}
}
}
这是我为RxUtils.applySchedulersAndErrorMapper()
收到null的堆栈跟踪java.lang.NullPointerException
答案 0 :(得分:1)
如果它与SDK有关,它可能不会在单元测试中工作。你没有包含你的进口,所以一眼就看不出来,但我从经验中知道你不能在单元测试中使用它
AndroidSchedulers.mainThread()
您需要将它替换为Schedulers.trampoline()
如何设置自定义调度程序以进行测试的示例
请注意,这只是一个示例,还有其他有效的解决方案。
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)
}
}
}
}
在您的测试中:
@Before fun setup() {
RxUtils.mainScheduler = Schedulers.trampoline()
RxUtils.ioScheduler = Schedulers.trampoline()
}
@After fun teardown() {
RxUtils.mainScheduler = AndroidSchedulers.mainThread()
RxUtils.ioScheduler = Schedulers.io()
}
编辑以回复更新的帖子,其中包含有关测试的更多信息
首先,你应该发布更多代码。令人沮丧的是不得不用滴水和单调把它拉出来。无论如何。您有以下内容:
@Mock
private UserService userService;
这会创建一个模拟UserService
,当然,它不会存根任何东西。当您调用userService.anyFunctionAtAll()
时,默认情况下它将返回null。你的NPE就在那里。你必须存根。例如:
Mockito.when(userService.anyFunctionAtAll()).thenReturn(somePredeterminedValue)
有关详细信息,请参阅Mockito website。