我会像这样测试主持人:
class MostPopularPresenter @Inject constructor(val mostPopularUseCase: MostPopularUseCase)
: Presenter<MostPopularView>() {
fun requestMostPopular(page: Int, update: Boolean) {
if (page <= 6)
mostPopularUseCase.execute(MostPopularObserver(), MostPopularUseCase.Params.createQuery(page, 15, update))
}
inner class MostPopularObserver : DisposableSingleObserver<MostPopularModel>() {
override fun onSuccess(t: MostPopularModel) {
this@MostPopularPresenter.view?.populateRecyclerList(t)
}
override fun onError(e: Throwable) {
this@MostPopularPresenter.view?.showError()
}
}
}
我有问题如何模拟观察者并强制它在成功时抛出错误或返回值。我正在使用mockito / junit。有人能指出我如何实现它吗?也许我的代码是不可测试的?
答案 0 :(得分:1)
通常情况下,绝对不可能进行测试的情况很少。据我所知,你有几个选择:
所有这些变体都可以使用并列在这里:
// observer in constructor
class MostPopularPresenter @Inject constructor(val mostPopularUseCase: MostPopularUseCase, val observer: DisposableSingleObserver<MostPopularModel> = MostPopularObserver())
: Presenter<MostPopularView>() {
// observer as property
internal var observer: DisposableSingleObserver<MostPopularModel> = MostPopularObserver()
// observer in function
fun requestMostPopular(page: Int, update: Boolean, observer: DisposableSingleObserver<MostPopularModel> = MostPopularObserver()) {
if (page <= 6)
mostPopularUseCase.execute(observer, MostPopularUseCase.Params.createQuery(page, 15, update))
}
}
internal class MostPopularObserver : DisposableSingleObserver<MostPopularModel>() { ... }
如果我们使用DisposableSingleObserverFactory
并在需要时创建观察者,那就更好了。
class MostPopularPresenter @Inject constructor(val mostPopularUseCase: MostPopularUseCase, val observerFactory: DisposableSingleObserverFactory<MostPopularModel> = MostPopularObserverFactorty())
: Presenter<MostPopularView>() {
internal var observerFactory: DisposableSingleObserverFactory<MostPopularModel> = MostPopularObserverFactory()
fun requestMostPopular(page: Int, update: Boolean, observerFactory: DisposableSingleObserverFactory<MostPopularModel> = MostPopularObserver()) {
if (page <= 6)
mostPopularUseCase.execute(observerFactory.create(), MostPopularUseCase.Params.createQuery(page, 15, update))
}
}
internal class MostPopularObserver : DisposableSingleObserver<MostPopularModel>() {
答案 1 :(得分:1)
observer
是一个不应该进行真正测试的对象。它已经在第三个开发人员开发时已经过测试,虽然有些人说,出于某种原因,你还应该测试第三方库,以确保它不会破坏你的代码版本之间。
所以,如果你不测试observer
...你如何测试你的代码?简单地说,您真正需要测试的是演示者本身。在observer
内运行的代码是演示者的一部分。因此,不要嘲笑observer
模拟useCase
:
test useCaseFails() {
val usecase = // mock use case
when(usecase.execute(...))
.thenAnswer(/* receive the observer as first parameter
and make it emit an error */)
val presenter = ...
presenter.requestMostPopular(...)
// assert that presenter.view?.showError has been called
}
另一种方法(至少这是我通常编码的方式)是让useCase
返回observable
并在presenter
中订阅:
class MostPopularPresenter @Inject constructor(val mostPopularUseCase: MostPopularUseCase)
: Presenter<MostPopularView>() {
private var lateinit observer : Disposable
fun requestMostPopular(page: Int, update: Boolean) {
if (page <= 6)
disposable = mostPopularUseCase.execute(MostPopularUseCase.Params.createQuery(page, 15, update))
.subscribe(t -> view?.populateRecyclerList(t),
e -> view?.showError())
}
}
通过这种方式,您可以轻松模拟useCase
,以便返回您可以控制的Subject
:
test useCaseFails() {
val usecase = // mock use case
val subject = PublishSubject()
when(usecase.execute(...))
.thenReturn(subject)
val presenter = ...
presenter.requestMostPopular(...)
subject.emitError(...) // <- pseudocode
// assert that presenter.view?.showError has been called
}